集合对于java的学习至关重要,所以一定要学习好集合 。
集合:collection
集合中存储的都是对象,没有基本数据类型
由于集合Collection是一个接口,所以不能创建对象,也就不能直接调用Collection的方法,只能通过Collection的子类来创建对象,Collection的子类之一:ArrayList
可以通过向上转型来创建ArrayList的对象调用Collection的方法 。
写法如下:
Collection c=new ArrayList<>();
为什么要向上转型呢?因为Collection是接口,不能直接创建对象,只能通过子类向上主转型来创建对象,调用方法。
ArrayList:大小可变的数组。
集合与数组的区别与联系:
大小上:数组的大小是固定不变的,而集合的长度是可变的
数组中存储的都是同种类型的元素,而集合存储的是任意数据类型的对象,集合中不能存储基本数据类型。
相同点:数组和集合都是容器,都是存储数据的。
为什么要引入集合的概念呢,我是这样理解的:
***首先,数组存储的是基本数据类型,这些基本数据类型不是对象,没有方法可调用,所以数组元素的增删改查非常的不方便,而集合中存储的都是对象,增删改查的话都可以通过调用对象的方法来实现,非常方便(CSDN编辑模式没有删除线,所以加粗,斜体代表删除线,手动删除线!!!)。***(更改:被删除线划掉的这句话对了一半,数组中可以存储对象,例如String类型的字符串,就是对象,但是只能存储同一种类型的对象,使用起来不方便。!!)
还有就是数组中只能存储相同类型的数据,而集合中可以存储不同类型的对象,也很方便,还有就是数组不可变,集合可变。
集合中存储的都是对象,存储基本数据类型的话,也都是存储的包装类,比如存123 ,存储的是Integer;
ArrayList的常用方法:
add() 添加元素到集合中。
addall() 将指定集合中的全部元素添加到对象集合中。
clear() 将集合中全部元素清空。
contains(obj): 判断是否包含obj对象,包含返回true.
toString() 方法是需要重写的,因为没有重写的toString()方法,返回的是类全名@地址的哈希值,经过重写以后,可以返回对象的元素的值,更清晰一点。
1 c.add(new Person("李四",28));
2 syso(c.contains(new Person("李四",28)));
3 打印的是false,因为都是新创建的对象,地址值不同,equals方法没有重写,所以返回false
1 c.add(1);
2 c.add(2);
3 c.add(3);
4 syso(c.contains(4));
5 返回false,因为contains判断的是数值是否相同,而不是数据类型是否相同
对于方法重写的形象描述:
父亲是经营生意的,儿子游手好闲,所以为了让儿子有正经事情做,父亲把他的生意交给了儿子打理,这就好比子类直接继承父类的方法,没有重写。
父亲是经营生意的,儿子爱好法律,并不喜欢父亲的生意,所以儿子去了律师事务所,这就好比儿子重写的父亲的方法,重写。
复制代码
1 public class T{
2
3 main{
4 S1 s=new S1("zhangsan",18);
5 S1 s2=new S1("zhangsan",18);
6 S1 s3=s
7 syso(s==s2); //false ==号就是判断是否是同一个对象
8 syso(s.equals(s2)); //false 因为没有重写,所以判断地址
9 syso(s==s3); //true 两个对象地址完全相同,所以判断为相同,下同
10 syso(s.equals(s3)); //true
11
12 }
13
14 }
15 class S1{
16 name
17 age
18 构造
19 }
复制代码
没有重写前的equals方法和==是相同的,都是判断地址,看是不是一个对象。
重写equals方法:第一种为简略的写法,有很多不合理,不方便的地方,比如,没有判断是否为本对象,是否为同一类,本对象是否为null, 是否name值为null。
复制代码
1 package CollectionDemo; //这是一种简略的写法,破绽很多
2
3 public class Demo2 {
4
5 public static void main(String[] args) {
6 S1 s=new S1(18,"zhangsan");
7 S1 s2=new S1(18,"zhangsan");
8 System.out.println(s.equals(s2));
9
10
11 }
12
13 }
14 class S1{
15 int age;
16 String name;
17 public S1(int age, String name) {
18 super();
19 this.age = age;
20 this.name = name;
21 }
22 public boolean equals(Object obj) {
23 S1 s=(S1)obj; 因为obj为父类,父类不能调用子类的方法和属性,所以 obj无法调用name属性和age属性,所以要向下转型,将obj转为S1类型
24 if((this.age==s.age)&&(this.name.equals(s.name)))
25 return true;
26 else {
27 return false;
28 }
29
30 }
31
32 }
复制代码
第二种 健全的equals重写方法:
复制代码
1 public boolean equals(Object obj) {
2 if(this==obj) { //判断是否是本对象,这里的this指的是调用equals方法的对象。
3 return true;
4 }
5 if(obj==null) { //判断本对象是否为null
6 return false;
7 }
8 if(this.getClass()!=obj.getClass()) { //判断是否为同一类,若不为同一类,则无比较的意义。
9 return false;
10 }
11 S1 s=(S1)obj; //向下转型,因为父类对象obj无法访问子类的属性
12 if(s.name==null) {
13 return false;
14 }
15 if(!s.name.equals(this.name)) {
16 return false;
17 }
18 if(!(this.age==s.age)) {
19 return false;
20 }
21 return true;
22 }
复制代码
编译期会提供重写equals方法,不过了解一下更好。
复制代码
1 class F{
2
3 public void fun1(int a){};
4 }
5
6 class Zi extends F{
7 public void fun1(); //问这两个fun1方法是什么关系,是重载关系 因为子类会继承父类的所有方法,所以子类也有这个fun1()方法,而且两个方法的参数列表不同,所以为重载。
8 }
复制代码
老师的笔记如下:
Collection:表示集合体系结构中的根接口,里面存储的是一组对象。
Object类:所有类的层次结构中的根类。 无论是否显式继承或隐式继承,都继承该类。
Object类的常用方法:
toString()方法:返回该对象的字符串表示形式,默认格式:类的完全限定名(类全名)@十六进制的哈西码值
注意:该方法不能满足要求,就需要重写。
equals(obj):默认表示判断对象与参数对象是否相同,等同于==号的结果。
注意:==一般用于比较基本数据类型,比较对象时比较的是对象的内存地址。
equals方法用来比较对象,如果不满足要求,可以重写。
equals方法出现的原因就是==不能被重写,负责equals方法毫无意义!!!