GitHub:Aure219/JAVA-homework: JAVA-homework (github)
1选择Windows Preferences,选择Configuration,点击Add Entry
添加自己的name 和 email
然后生成公钥私钥
复制一下
接下来打开GitHub
点击Settings
然后如图操作
输入title和key
key就是之前复制的公钥
远程仓库new一个
取名
复制SSH 等一下要用到
1.先新建一个Project
2.然后new一个class
取个名字,然后最好勾上圈出来的
接下来写代码
提交到本地仓库
然后再commit
点击你要上传的,通常后缀是.java
再点击2处的绿的加号
然后再3处随便写点东西
最后点最底部的push
这时把刚才拷贝的粘贴到这里来
接下来就一直点,
出现下面这个页面应该就是成功了
然后回到GitHub 发现上面出现了你的代码即可
盘符切换:e:回车
查看当前路径下的内容:dir
进入单级目录:cd 目录
回退到上一级目录:cd…
进入多级目录:cd 目录1目录2
回退到盘符目录:cd
清屏:cls
退出命令提示符窗口:exit
hello world案例分析
1.先建一个文本文档,修改名称,后缀改成.java
2.用记事本打开,编写程序,并保存
3.编译运行
编译:javac 文件名.java
运行:java 文件名
1.打代码可以打一些,再打alt+/,
2.鼠标定位在某一行,按住shift+方向键,可以选取多行,ctrl+是注释多行
1.输入什么,输出什么
Scanner in =new Scanner(System.in);System.out.println("echo"Line());//加前缀的话,要带上加号哦,加号起到连接字符串的作用,如果是print也是打印,只不过他不会自动换行
2.加法的使用
加法的使用方法,是起到连接字符串的作用还是运算的作用
注意最上面加了一行代码import java.util.Scanner;(若使用了第十行,则要加这行代码)
int [] arr1 = new int[10]
int [] arr1 = new int[n]
int [] arr1 = {1,2,3,4,5,6}
int [][] arr1 = new int[3][5]
int [] arr1 = new int[10];
arr1[0]=5;
int [] arr2 = arr1;
arr2[0]=16;
System.out.println(arr1[0]);//输出的是16
//因为arr1相当于管理者,而非数组本身,创建arr2,数组其实还是原来的数组,相当于arr1和arr2管理同一个数组
int[]a={1,2,3};
int[]b={1,2,3};
System.out.println(a==b);//输出false,尽管元素相同,因为a,b管理的两个不同的数组
String.format("%.3f",num)
表示保留三位小数 ,记住要加双引号哦
float a=8.2//编译失败,因为看到小数点,会自动认为是double类型,此时需要强制类型转换。
下面两种都可以
float a=8.2f;
float a=(float)8.2;
注意:这和C语言有点不一样的
保留两位小数并且向下取整
private static double getTwoDecimalPlaces(double number) {return (double) Math.floor(number*100)/100;
}
保留两位小数并向下取整,如果是向上取整,用ceil即可
如果要保留三位小数呢,*1000 / 1000 依此类推
多组输入
Scanner input = new Scanner(System.in); int a, b; while(input.hasNextInt()){//重点在这里a = Int();b = Int(); System.out.println(a + b); }
1.使用sqrt
Math.sqrt()
2 生成随机函数
(int) (Math.random()*10)
随机产生0到9
1 . 任意单个字符,除了换行符外
一个点就代表一个字符
String str="Java";
System.out.println(str.matches("..va"));//输出true
System.out.println(str.matches(".va"));//输出false
2 (ab|cd) ab或者cd
String str="ten";
System.out.println(str.matches("t(en|im)"));//输出true
//单个字符或者多个字符也是可以的哦
String str1="Java";
System.out.println(str1.matches("J(a|v)va"));//输出true
System.out.println(str1.matches("(Jav|JJJ)a"));//输出true
3 [abc] a或b或c
String str="Java";
System.out.println(str.matches("Ja[uw]a"));//输出false
System.out.println(str.matches("Ja[uvw]a"));//输出true
4 [ [ [^abc ] ] ] 除了a、b或者c之外的任意字符
String str1="Java"; System.out.println(str1.matches("Ja[^abcdv]a"));//输出false
System.out.println(str1.matches("Ja[^abcd]a"));//输出true
5 [a-z] a到z
是区分大小写的,两端都是闭区间
String str1="Java";
System.out.println(str1.matches("Ja[A-V]a"));//输出false
System.out.println(str1.matches("Ja[a-v]a"));//输出true
6 [a-e[m-p]] a到e或者m到p
String str1="Java";
System.out.println(str1.matches("[A-G[I-M]]av[a-d]"));//输出true
7 [a-e&&[c-p]] a到e与c到p的交集
String str1="Java";
System.out.println(str1.matches("[A-P[I-M]]av[a-d]"));//输出true
Tips 为什么正则表达式是d,而敲的时候要\d呢
因为反斜杠是一个特殊的字符,在字符串中开始转移序列,因此用 来表示
8 d 一位数字,等同于0-9
String str1="Java23";
System.out.println(str1.matches("Java[\d][\d]"));//输出true,两位数字就要用两次哦
System.out.println(str1.matches("Java\d\d"));//输出true,意外发现,不需要方括号也可以
9 D 一位非数字
String str1="Java23";
System.out.println(str1.matches("[\D]ava23"));//输出true System.out.println(str1.matches("J\Dva\d\d"));//输出true
10 w 单词字符
单词字符是任意的字母,数字或者下划线字符。
11 W 非单词字符
12 s 空白字符
13 S 非空白字符
14 p* 0次或者多次出现模式p
多个字母要加括号哦
String str1="ababa";
System.out.println(str1.matches("(ab)*"));//输出false
System.out.println(str1.matches("(ab)*a"));//输出true
String str2="ababab";
System.out.println(str2.matches("(ab)*"));//输出true
String str3="aaaaaa";
System.out.println(str3.matches("(ab)*"));//输出false
System.out.println(str3.matches("aaaaaa(ab)*"));//输出true
15 p+ 一次或者多次出现模式p
String str1="aaa";
System.out.println(str1.matches("a+b*"));//输出true
16 p? 0次或者1次出现模式p
String str1="aaa";
System.out.println(str1.matches("b?"));//输出false
System.out.println(str1.matches("aaab?"));//输出true
17 p{n} 正好出现n次模式p
18 p{n,} 至少出现n次模式p
19 p{n,m} n到m出现模式p
String str1="abb";
System.out.println(str1.matches("a{1,9}bb"));//输出true,说明是包含区间端点的 System.out.println(str1.matches("a{2,9}bb"));//输出false
20 p{P} 一个标点字符
String str1="j!erw";
System.out.println(str1.matches("j\p{P}erw"));//输出true
示例:
1.社会安全号的模式为xxx-xx-xxxx,x是一位数字
String str1="111-22-2222";
//表示数字恰好出现了3次-恰好出现了2次-恰好出现了4次
System.out.println(str1.matches("[\d]{3}-[\d]{2}-[\d]{4}"));//输出true
2.偶数表示
偶数是以数字0、2、4、6、8结尾
String str1="112";
System.out.println(str1.matches("[\d]*[02468]"));//输出true,结尾是偶数就行了,因为前面的[\d]*已经读取了前面的数字了
3 电话号码表示模式是(xxx)-xxx-xxxx, x代表一位数字,其中不能以0开头
String str1="(123)-123-1231";
System.out.println(str1.matches("\([\d]{3}\)-[\d]{3}-[\d]{4}"));//输出true
String str1="(123-123-1231";
System.out.println(str1.matches("\([\d]{3}\)-[\d]{3}-[\d]{4}"));//输出false,少括号不行哦
tips ()在正则表达式中是特殊字符,用于对模式分组。为了在正则表达式中表示字面值,必须使用
4.假定姓由最多25个字母组成,并且第一个字母为大写
String str1="Adsfds";
System.out.println(str1.matches("[A-Z][a-z[A-Z]]{1,24}"));//输出true
tips 不能随便将空白符放入到正则表达式中,会报错 ,编译都过不了
5 java标识符
标识符必须以字母,下划线或者以美元符号($)开头,不能以数字开头
标识符是一个由字母,数字,下划线或美元符号组成的字符序列
String str1="Adsfds$";
System.out.println(str1.matches("[a-z[A-Z][$]][\w|$]*"));//输出true
如果类C1继承自类C2,那么就将C1称为子类(又叫继承类或派生类),C2称为超类(又叫父类或基类)
public class GeometricObject {private String color = "white";private boolean filled;private java.util.Date dateCreated;//这是我没见过的public GeometricObject() {dateCreated = new java.util.Date();//获取对象创建的时间}public GeometricObject(String color,boolean filled){dateCreated = new java.util.Date();lor = color;this.filled = filled;}public String getColor() {return color;}public void setColor(String color) {lor = color;}public boolean isFilled() {return filled;}public void setFilled(boolean filled) {this.filled = filled;}public java.util.Date getDateCreated(){return dateCreated;//返回时间}
//表示Circle继承GeometricObject
public class Circle extends GeometricObject{private double radius;public Circle() { }public Circle(double radius) {this.radius=radius;} //重载的构造方法,通过调用setColor和setFilled方法来设置color和filled的属性,这两个方法是在父类中定义的public Circle(double radius,String color,boolean filled) {this.radius =radius;setColor(color);setFilled(filled);//lor=color;//this.filled=filled;//这种写法错误,因为他们是GeometricObject类中的私有数据域,不能被其他任何类访问,唯一读取和改变color和filled的方法就是通过他们的获取方法和设置方法。//用super关键字可以改写成下面的代码//super(color,filled)//this.radius=radius}public double getRadius() {return radius;}public void setRadius(double radius) {this.radius=radius;}public double getArea() {return radius*radius*Math.PI;}public double getDiameter() {return 2*radius;}public double getPerimeter() {return 2*radius*Math.PI;}public void printCircle() {System.out.println("The circle is created "+getDateCreated()+" and the radius is "+radius);}
}
public class Rectangle extends GeometricObject{
private double width;
private double height;public Rectangle() {
}public Rectangle(double width,double height) {this.width=width;this.height=height;
}public Rectangle(double width,double height,String color,boolean filled) {this.width=width;this.height=height;setColor(color);setFilled(filled);
}public double getWidth() {return width;
}public void setWidth(double width) {this.width=width;
}public double getHeight() {return height;
}public void setHeight(double height) {this.height=height;
}public double getArea() {return width*height;
}public double getPerimeter() {return 2*(width+height);
}
}
public class EX11_4 {public static void main(String[] args) {Circle circle=new Circle(1);System.out.println("A circle "String());System.out.println("The color is "Color());System.out.println("The radius is "Radius());System.out.println("The area is "Area());System.out.println("The diameter is "Diameter());Rectangle rectangle=new Rectangle(2,4);System.out.println("nA rectangle "String());System.out.println("The area is "Area());System.out.println("The perimeter is "Perimeter());}}
super关键字:
子类可以继承父类的方法和可访问的数据域,但是不能继承父类中的构造方法,这时就只能用关键字super。
基本语法:1.super() 调用父类的无参构造方法
2.super(argumes) 调用与父类匹配的构造方法
注:super()或super(arguments)必须出现在子类构造方法的第一行,这是显式调用父类构造方法的唯一方式
原因:因为在任何情况下,构造一个类的实例时,将会调用沿着继承链的所有父类的构造方法,如果没有被显式调用,编译器会自动地将super()作为构造方法的第一条语句。所以如果没有把显式调用放在第一行,编译器在执行到第一行时会自动将super()加上去,然后再执行到下面时就会出错了
来看一个错误代码
public class Apple extends Fruit{}class Fruit{public Fruit(String name){System.out.println(".........");}
}
由于Apple没有显式定义构造方法,所以Apple的默认无参构造方法会被隐式调用,即调用Fruit的无参构造方法(因为Apple是Fruit的子类),然而,因为Fruit显式地定义了构造方法,所以Fruit没有无参构造方法,因此,改程序不能被成功编译。
设计指南:一般情况下,最好为每个类提供一个无参构造方法,以便于对该类进行继承,同时避免错误。
方法重写:子类从父类中继承方法,但有时需要修改父类中定义方法的实现
重写与重载的区别:方法重写发生在具有继承关系的不同类中,而方法重载可以发生在同一个类中,也可以发生在具有继承关系的不同类中。
方法重写具有同样的签名,方法重载具有同样的签名但是不同的参数列表
poly + morphism
许多 形态 即多种形态
extends继承或者implements实现,是多态性的前提。
多态意味着父类型可以引用子类型的对象
继承关系使一个子类能继承父类的特征,并且附加一些新特征。子类是它的父类的特殊化,每个子类的实例都是其父类的实例,但是反过来并不成立。例:每个圆都是几何对象,但并非每个几何对象都是圆。因此,总可以将子类的实例传给需要父类型的参数
Eg1:
//父类
public class Father {public void method() {System.out.println("父类方法");}public void methodf() {System.out.println("父类特有方法");}
}
//子类
public class Son extends Father{@Overridepublic void method() {//hod()这样就可以调用父类的method方法,super关键字,Cannot use super in a static context,主函数里面用不了吧System.out.println("子类方法");}
}
/*代码体现多态性的一句话,父类引用指向子类对象格式:父类名称 对象名 = new 子类名称();*/
public class Demo1 {public static void main(String[] args) {Father obj = new Son();hod();//输出 子类方法hodf();//输出 父类特有方法}
}
Eg2:
public class Father {int num=20;public void method() {System.out.println(num);}
}
public class Son extends Father{int num=10;int age=16;@Overridepublic void method() {System.out.println(num);}
}
/*访问成员变量的两种方式:1.直接通过对象名称访问成员变量:等号左边是谁,优先用谁,没有则向上找2.间接通过成员方法访问:看该方法属于谁,优先用谁,没有则向上找*/
public class Demo1 {public static void main(String[] args) {Father obj = new Son();System.out.println(obj.num);//输出20// System.out.println(obj.age);错误写法,不会向下找的,只会向上找,找objcect,而object里面肯定没有hod();//输出10,如果子类没有方法重写的话就输出20}
}
Eg3:
public class Father {public void method() {System.out.println("父类方法");}public void methodf() {System.out.println("父类特有方法");}
}
public class Son extends Father{public void method() {System.out.println("子类方法");}public void methods() {System.out.println("子类特有方法");}
}
/*在多态的代码中,成员方法的访问规则是:看new的是谁,就优先用谁,没有则向上找编译看左边,运行看右边*/
public class Demo1 {public static void main(String[] args) {Father obj = new Son();hod();hodf();hods();//编译报错,因为父类没有methods这个方法}
}
总结:多态:基类型对象访问派生类重写的方法
对象的向上转型,其实就是多态写法
父类名称 对象名 = new 子类名称(); //Animal animal = new Cat() 创建了一只猫,把他当作动物
含义:右侧创建一个子类对象,把他当做父类来看待使用==注==:向上转型一定是安全的,从小范围到大范围。但也有一个弊端,就是对象一旦向上转型成父类,那么就无法再调用子类原本特有的内容。(即上面Demo1里面注释编译报错的那一行,因为methods是子类特有的内容),此时就有了向下转型类似于:double num=100;//正确,int->double
对象的向下转型,其实就是一个【还原】的动作
格式:子类名称 对象名 = (子类名称) 父类对象;(类似于强制类型转换)
含义:将父类对象,还原成本来的子类对象
Animal animal = new Cat();//本来是猫,向上转型为动物
Cat cat = (Cat) animal;//本来是猫,已经被当作动物了,现在还原成原来的猫
注意:a.必须保证对象本来创建的时候,就是猫,才能向下转型成为猫,如果对象原来创建的时候不是猫,现在非要向下转型成为猫,就会报错。(编译不会出错,运行会出错)
那怎么知道父类引用的对象中本来是什么子类呢?
这时就需要使用instanceof
public class Demo2 {public static void main(String[] args) {giveMeAPet(new Dog());}
}public static void giveMeAPet(Animal animal){if(animal instanceof Dog){Dog dog = (Dog) animal;dog.watchHourse();}if(animal instanceof Cat){Cat.cat = (Cat) animal;cat.catchHouse();}
}
//给我了一只动物,但我只知道她是动物,所以此时要用instanceof判断他是什么,从而物尽其用。
1.循环调用基类对象,访问不同派生类方法
public static void main(String[] args) {
GradedActivity[] tests = new GradedActivity[3];// 第一次考试采用五级计分制,考了75tests[0] = new GradedActivity();tests[0].setScore(75);// 第二次考试采用二级计分制(P或者F)。总共20题,每题分值相同,考生答错5题。// 通过的最低分数线是60分tests[1] = new PassFailExam(20, 5, 60);// 第三次是期末考试也采用五级计分制. 总共50题,每题分值相同,考试答错7题tests[2] = new FinalExam(50, 7);// 显示每次考试的分数和等级for(int i=0; i<tests.length; i++){showValue(tests[i]);}
}public static void showValue(GradedActivity exam){System.out.println("Score: " + Score()+ "t" + "Grade: " + Grade());}
2.实参是派生类,形参是基类
图形类(Geometry)是矩形和圆形等具体形状类的共同父类,他有一个getArea方法的功能是计算图形的面积,但是在图形类中并不知道具体的形状,因此无法计算,也就是说,getArea方法的方法在父类中实际上没有任何意义。
解决办法:通过abstract关键字将getArea方法修饰为抽象的,此时的方法称为抽象方法。
抽象方法是出现在基类中的一种方法,但要求在派生类中被重写。(如果派生类没有重写抽象方法,编译器就会报错,抽象方法被用来确保派生类会实现这个方法)
格式:访问修饰符 abstract 返回类型 方法名(参数列表);
例:public abstract void getArea();//关键字abstract 出现在方法头中,方法头以分号结尾
若类含有抽象方法,则类必须以abstract关键字声明为抽象类。
格式: public abstract class 类名
注意
1.不论抽象类是否含抽象方法,其都不允许实例化,即不能创建抽象类的对象,因为其描述的是抽象概念。它只能作为其他类的基类。
2.若父类是抽象类,且子类不想成为抽象类,则子类必须将父类中的所有抽象方法重写为带方法体的普通方法,否则子类仍必须是抽象类。
super的使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o4EHFcaL-1690521335713)(.png)]
调用父类的构造方法
1.关键字不同:
① 继承抽象类的关键字是extends,而实现接口的关键字是implements;
②定义抽象类的关键字是abstract class,而定义接口的关键字是interface;
2.权限修饰不同:抽象方法可以有public、protected和default这些修饰符(缺省情况下默认为public),而接口方法只能是public ;
3.抽象类中可以有构造方法,而接口中不能有构造方法;
如果写了构造方法,编译报错:Interfaces cannot have constructors
4.抽象类中既可以有抽象方法也可以有普通方法,接口中只能有抽象方法;
注:从jdk1.8开始允许接口中出现非抽象方法,但需要使用default关键字修饰。
意义:
1.假如你接口中有很多的抽象方法,但是实现类中有时候并不需要用到那么多的抽象方法,但是又要全部重写,就会很麻烦,这时如果使用非抽象方法,就可以在实现类中重写需要使用到的抽象方法即可,大大减少了代码量。
2.当我们在接口中增加一个抽象方法时,这时所有实现接口的类中都要重写这个方法,就有牵一发而动全身的麻烦。那么如果用非抽象方法,就可以根据实际需要重写该非抽象方法。
5.抽象类中增加方法可以不影响子类,而接口中增加方法通常都影响子类。
理解:因为在抽象类中,可以定义非抽象方法,这时就不需要在子类中重写了,而接口中增加方法,这方法肯定是抽象类方法,则必须要在子类中重写。(为什么是通常呢,因为上面第四点提到,在jdk1.8开始,允许接口中出现非抽象方法)
6.抽象类中的变量可以是普通变量,接口里定义的变量只能是公共的静态的常量;
实际操作中发现定义变量时没写public static final也不会报错,因为接口只能是公共的静态常量的,编译器默认会加上,同理,定义方法时没写public abstract也不会报错
7.抽象方法可以继承单个类和实现多个接口,接口可以多继承接口;
abstract class Demo{abstract void printfa();//抽象方法void printfb();//编译报错,add bodyvoid printfb() {//非抽象方法}}interface Demo1{void printfab();void printfa() {//编译报错,因为接口中必须是抽象方法 }default void printfb() {//加上default可以了 }}
(1) 都可以被继承
(2) 都不能被实例化
(3) 都可以包含方法声明
(4) 派生类必须实现未实现的方法
转:Java中abstract class 和 interface 的解释和他们的异同点(转) - petercao - 博客园 (cnblogs)
abstract class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is-a"关系,即父类和派生类在概念本质上应该是相同的。对于interface来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已。
eg:
假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型。
abstract class Door {abstract void open();abstract void close();
}//或者
interface Door{void open();void close();
}
如果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢?
方案1:
简单的在Door的定义中增加一个alarm方法
abstract class Door{
abstract void open();
abstract void close();
abstract void alarm();
}// 或者
interface Door{
void open();
void close();
void alarm();
}
那么具有报警功能的AlarmDoor
的定义方式如下:
class AlarmDoor extends Door{
void open(){}
void close(){}
void alarm(){}
}// 或者
class AlarmDoor implements Door{
void open(){}
void close(){}
void alarm(){}
}
这种方法违反了面向对象设计中的一个核心原则 ISP (Interface Segregation Principle),在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变(比如:修改alarm方法的参数)而改变。
什么是ISP?
在软件工程领域,接口隔离原则(ISP)规定不应强迫客户端依赖它不使用的方法。ISP将非常大的接口拆分为更小和更具体的接口,以便客户端只需知道它们感兴趣的方法。这种缩小的接口也称为角色接口。ISP旨在使系统分离,从而更容易重构,更改和重新部署。ISP是面向对象设计的五个SOLID原则之一,类似于GRASP的高内聚原则。
大接口拆分为小接口:就是一个类实现多个接口。
不应强迫客户端依赖它不使用的方法:那就是说几个小接口要合理划分
方案2:
既然open、close和alarm属于两个不同的概念,根据ISP原则应该把它们分别定义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用 abstract class 方式定义;两个概念都使用interface方式定义;一个概念使abstract class 方式定义,另一个概念使用interface方式定义。显然,由于Java语言不支持多重继承,所以两个概念都使用abstract class方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。
如果我们对于问题领域的理解是:AlarmDoor
在概念本质上是Door,同时它有具有报 警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class在Java语言中表示一种继承关系,而继承关系在本质上是"is-a"关系。所以对于Door这个概念,我们应该使用 abstract class方式来定义。另外,AlarmDoor
又具有报警功能,说 明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义.
abstract class Door{
abstract void open();
abstract void close();
}
interface Alarm{
void alarm();
}
class Alarm Door extends Door implements Alarm{
void open(){}
void close(){}
void alarm(){}
}
总结:abstract class表示的是"is-a"关系,interface表示的是"like-a"关系
1.ArrayList类
存储在ArrayList
中的元素必须是一种对象
package hhhhh;import java.util.ArrayList;
import java.util.Scanner;public class EX11_9 {public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();//建立一个列表Scanner input =new Scanner(System.in);System.out.print("Enter integers (input ends with 0): ");int value;do {value Int();if(!ains(value)&&value!=0)list.add(value);//添加元素}while(value!=0);for(int i=0;i<list.size();i++) {System.out.(i)+" ");//访问下标是i的元素}//另一种循环遍历的方式/*for(int i:list) { System.out.println(i); }*/}}
Reward:建立列表的方式以及 多组输入遇到某个值退出的操作
//列表的排序 java.util.Collections.sort(list);list.sort(null);//删除元素
ve(value);//删除下标为value的,但是如果value是对象的话,就可以删除改对象//判断元素是否存在
System.out.ains(5));//判断列表中是否有5//找元素的位置
System.out.println(list.indexOf(3));//找列表中3的位置(从0开始的)//设置元素
list.set(1, 0);//下标为1的赋值0//获取元素
(i);//获取下标为i的值//遍历操作
1、通过索引值访问,可顺序遍历,也可随机访问。for(int i=0;i<list.size();++i) {System.out.(i));}
2.通过ForEach循环访问,实现顺序遍历for(Integer v:list) {System.out.println(v);}
3.通过迭代器访问,实现顺序遍历。Iterator it=list.iterator();while(it.hasNext()) {Integer x=(();System.out.println(x);}
或者Iterator it=list.iterator();while(it.hasNext()) {//Integer x=(();System.out.());}
2.LinkedList类
LinkedList
也像ArrayList
一样实现了基本的List接口。LinkedList
还添加了可以使其用作栈、队列或双端队列的方法。
LinkedList <Integer> l=new LinkedList<Integer>();l.push(1);//元素压入栈中l.push(2);l.pop();//删除栈顶元素System.out.println(l.peek());//取出栈顶元素,输出1(说明这是栈,后进先出)
小结:
ArrayList
数组线性表的特点为:类似数组的形式进行存储,因此它的随机访问速度极快。
ArrayList
数组线性表的缺点为:不适合于在线性表中间需要频繁进行插入和删除操作。因为每次插入和删除都需要移动数组中的元素。
LinkedList
的链式线性表的特点为: 适合于在链表中间需要频繁进行插入和删除操作。
LinkedList
的链式线性表的缺点为: 随机访问速度较慢。查找一个元素需要从头开始一个一个的找。
1.HashSet类
HashSet <Integer>s= new HashSet<>();s.add(1);s.add(2);s.add(4);for(Integer x:s) {System.out.println(x);}
2.TreeSet类
public class Student implements Comparable{private String number;private String name;private int age;Student(String number,String name,int age){this.number=number;this.name=name;this.age=age;}public String toString() {return "学号:"+number+" 姓名:"+name+" 年龄:"+age;}public String getNumber() {return number;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic int compareTo(Object o) {Student p=(Student) o;if(age>p.age) return 1;else return -1;}
}
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Demo2 {public static void main(String[] args) {Scanner input = new Scanner(System.in);Set<Student> students = new TreeSet<Student>();while (true) {String number = ();if (number.equals("exit"))break;// java中判断字符串相等不能用==String name = ();int age = Int();students.add(new Student(number, name, age));}// 按年龄从小到大输出// 迭代器的写法Iterator <Student> it=students.iterator();while(it.hasNext()) {Student s=(();System.out.String());}// ForEach的写法for (Student student : students) {System.out.String());}}}
小结:
HashSet
和TreeSet
都有一个共同的特性就是集合的唯一性.TreeSet
只是多了一个排序的功能.
TreeSet
是一个有序的集合,它的作用是提供有序的Set集合。TreeSet
中的元素支持2种排序方式,自然排序(升序)或者根据创建TreeSet
时提供的 Comparator 进行排序。
1.HashMap
Map<String,Integer> mp=new HashMap<String,Integer>();mp.put("ac", 111);//存取数据mp.put("bc",12);System.out.("ac"));//获取键为ac的值System.out.ainsKey("ac"));//判断是否存在键为“ac”System.out.ainsValue(12));//迭代器遍历Iterator iterSet().iterator();while(iter.hasNext()) {Map.Entry entry=(Map.();System.out.Key()+" "Value());}Map<String,Integer> mp=new HashMap<String,Integer>();mp.put("111", 1);mp.put("121", 1);mp.put("311", 1);mp.put("114", 1);mp.put("123", 1);Iterator iterSet().iterator();while(iter.hasNext()) {Map.Entry entry=(Map.();System.out.Key()+" "Value());}
//输出
121 1
111 1
123 1
311 1
114 1
//和c++一样,也是随机的,并不是按顺序输出
Map<String,Integer> mp=new TreeMap<String,Integer>();mp.put("bc", 111);mp.put("ac",12);System.out.("ac"));System.out.ainsKey("ac"));System.out.ainsValue(12));Iterator iterSet().iterator();while(iter.hasNext()) {Map.Entry entry=(Map.();System.out.Key()+" "Value());}
输出
12
true
true
ac 12
bc 111//可见自然排序是升序
TreeMap
存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是自然排序,一种是定制排序,具体取决于使用的构造方法。
基本特点
Object 是所有类的父类,位于 java.lang包中 数组也是 Object 类的子类
Object 类的常用方法
toString()
可以将任何一个对象转换成字符串返回,返回值的生成算法为:
getClass().getName() + '@' + HexString(hashCode())
equals()
用来比较两个引用的虚地址。当且仅当两个引用在物理上是同一个对象时,返回值为true,否则将返回false。
hashCode()
获取对象的哈希码值,为16进制
Object类在 java.lang 包下,是所有类的根。任何类的对象,都可以调用 Object类中的方法,包括数组对象
Java 提供一系列包装类,以便将基础数据类型当做对象进行操作
在 java.lang 包中,对于每个基本数据类型都有一个对应的包装类
基本数据类型 | 包装类 |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
String s2 = "123";int a = Integer.valueOf(s2);System.out.println(123 == a);//trueint i = Integer.parseInt("18"); // 转换成整数
java.lang 包
创建方式
public class Test {public static void main(String[] args) {// 直接创建String str = "Hello World";// 使用构造方法String str1 = new String("Hello World"); //String 是一个类,这就能解释为什么 String 不属于基本类型/*** 两者区别:* 使用构造方法每次创建的都是一个 String 对象* 使用直接赋值的方式创建两个相同的对象,两者虚地址是一样的,实际上代表是相同的字符串*/}
}
常见方法
长度 | s.length() |
---|---|
去空格 | |
右对齐 | String.format(“%10s”,s) |
左对齐 | String.format(“%-10s”,s) |
时间转字符串 | |
包含查询 | |
下标查询 | s.indexOf(" "); |
判断是否为空 | if(s==null||s.isEmpty()) |
字符串比较 | equals |
String str="你好啊";String str1="12";String str2="123";System.out.ains("好啊"));//trueSystem.out.ains("你好啊啊"));//falseSystem.out.println(str.indexOf("好"));//1System.out.println(str.indexOf("你好"));//0System.out.println(str.indexOf("你"));//0System.out.println(str.indexOf("1"));//-1 找不到输出-1System.out.println(str1.equals(str2));//falseSystem.out.println(str1.equals("12"));//true//时间转字符串SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String time = simpleDateFormat.format(date);System.out.println(time);
下面来说明为什么在java中字符串比较要用equals
public class Main {public static void main(String[] args) {// 直接创建String s1 = "Hello World";String s2 = "Hello World";System.out.println(s1 == s2); // 返回 true , 因为使用等号赋值,比较的是值// 使用构造方法String str1 = new String("Hello World"); String str2 = new String("Hello World");System.out.println(str1 == str2); // 返回 false 虚地址不一样System.out.println(str1.equals(str2)); // 返回 true,这时候比较的就是值了// 所以一般使用 equals 方法比较字符串的值很常用 (equalsIgnoreCase 是忽略大小写比较) }
}
为什么字符串比较不使用==, 因为比较的是 虚‘地址,equalsIgnoreCase() 会忽略大小写比较字符串
// java.io.file/**我们可以使用File类的方法*创建一个文件/文件夹 *删除文件/文件夹*获取文件/文件夹*判断文件/文件夹是否存在*对文件进行遍历*获取文件的大小*File类是一个与操作系统无关的类,任何的操作系统都可以使用这个类中的方法*/
/** 绝对路径:是一个完整的路径* 以盘符开始的路径* C:\demo\b.txt* 相对路径:是一个简化的路径* 相对指的是相对与当前项目的根目录* 如果使用当前项目的根目录,路径可以简化书写* 例 C:\users\ideaprojects\homework\ 可以简化为* 注意:1.路径是不区分大小写的* 2.路径中的文件名称分隔符在windows中使用反斜杠,反斜杠是转义字符,两个反斜杠等于一个反斜杠*/
文件名称分隔符 Windows:反斜杠 Linux:正斜杠/
路径分隔符 Windows:分号; Linux:冒号:
两个获取路径的方法:
public String getPath();
public String getAbsolutePath();
//无论路径是绝对的还是相对的,返回的都是绝对路径
/** File(String pathname) 通过将给定路径名字符串转换为抽象路径名来创建一个新File实例* String pathname:字符串的路径名称* 路径可以是以文件结尾,也可以是以文件夹结尾* 路径可以是绝对路径,也可以是相对路径* 路径可以是存在的,也可以是不存在的* 创建File对象,只是把字符串路径封装为File对象,不考虑路径的真假情况*/
File f1=new File("C:\Users\14716\Desktop\leetcode\12.txt");System.out.println(f1);
/*
输出
C:Users14716Desktop
说明是重写了Object类的toString方法,打印的是路径
File类的一些判断功能
public boolean exists();
//此File表示的文件或目录是否实际存在
public boolean isDirectory();
//用于判断构造方法中给定的路径是否以文件夹(目录)结尾
public boolean isFile();
//用于判断构造方法中给定的路径是否以文件结尾
==注:==如果路径不存在,返回false
数据流又分为输入流和输出流
输入流:往内存中读叫输入流
输出流:从内存中往外些叫输出流
所有输入流都是 InputStream 类或者 Reader 类的子类
类名以 inputStream 结尾的类都是 InputStream 的子类
类名以 Reader 结尾的类都是 Reader类的子类
所有输出流都是 OutputStream 类 或者 Writer类的子类
类名以 OutputStrean结尾的类都是 OutputStream的子类
类名以 Writer结尾的类都是 Writer 类的子类
输入输出流又分为字节流和字符流
1.字节流:以字节为基本单位 , 在 java.io包中,大部分操作继承InputStream(输入字节流)类和OutputStream(输出字节流)类
2.字符流:两个字节为基本单位,专门处理字符串和文本,对于字符流进行操作的类主要是Reader(读取流)类和 Writer(写入流)类。
接下来是常用的三种读写文件的方式
对文件内容按字符读取
String dir = "E:\soft\aaa\a.txt";
File file = new File(dir);
//如果文件不存在,创建文件
if (!ists()) ateNewFile();
//创建FileWriter对象
FileWriter writer = new FileWriter(file);
//向文件中写入内容
writer.write("the first way to write and read");
writer.flush();
writer.close();//创建FileReader对象,读取文件中的内容
FileReader reader = new FileReader(file);
char[] ch = new char[100];
ad(ch);
for(char c:ch) {System.out.print(c);
}
System.out.println();
reader.close();
对文件内容进行整行读取
String dir = "E:\soft\aaa\b.txt";
File file = new File(dir);
//如果文件不存在,创建文件
if (!ists()) ateNewFile();
//创建BufferedWriter对象并向文件写入内容
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
//向文件中写入内容
bw.write("the second way to write and read");
bw.flush();
bw.close();
//创建BufferedReader读取文件内容
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((lineadLine())!=null) {System.out.println(line);
}
br.close();
以字节的形式写入文件,读取文件时先读取字节数组,再将字节数组转换为字符串形式
注意由于字节流的缘故,因此无法读取中文字符
String dir = "E:\soft\aaa\c.txt";
File file = new File(dir);
//如果文件不存在,创建文件
if (!ists()) ateNewFile();
//创建FileOutputStream对象,写入内容
FileOutputStream fos = new FileOutputStream(file);
//向文件中写入内容
fos.write("the third way to write and read".getBytes());
fos.close();
//创建FileInputStream对象,读取文件内容
FileInputStream fis = new FileInputStream(file);
byte[] bys = new byte[100];
while (ad(bys, 0, bys.length)!=-1) {//将字节数组转换为字符串System.out.println(new String(bys));
}
fis.close();
本文发布于:2024-02-01 11:49:58,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170675939936389.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |