一、Collection接口
Collection接口中所定义的方法:
1)一个容器对象可以放入不同的引用数据类型数据。
2)使用父类引用指向子类对象的原因:
ArrayList是Collection的实现类,Collection是一个接口,本身所有的方法都被ArrayList这些容器类实现,那么Collection的引用在调用自己方法的时候会有多态性,即实际调用的是子类方法,如果此时要将ArrayList换成HashSet,也只要换成HashSet的构造方法即可,其它涉及多态的部分都不要变,因为父类引用调用的原ArrayList的方法,也一定都被HashSet全部实现了,不会有不兼容的问题,因此这样去写,程序的扩展性极高。
1)"hello"和new Integer(100)都成功remove,而Name对象却没有remove,打印了false,容器中只剩下这一个元素。
2)remove()内部会调用每个对象的equals()方法,如果与传入的对象相等,则删除对象。
3、如果两个对象equals,那么这两个对象的hashCode应该相等。
容器类对象在调用remove、contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法(集合和列表中)和hashCode方法(映射中);因此,对于自定义的类型,需要重写equals和hashCode方法以实现自定义对象的相等规则。当一个对象用在HashMap类中作为键时,会用到hashCode方法,详细分析见JavaSE_32th_容器(类集框架)。
注意:相等的对象应该具有相等的hash codes。
增加Name类的equals和hashCode方法如下:
Collection接口中所定义的方法:
int size();
//返回此 collection 中的元素数。
boolean isEmpty();
//如果此 collection 不包含元素,则返回 true。
void clear();
//移除此 collection 中的所有元素(可选操作)。
boolean contains(Object element);
//如果此 collection 包含指定的元素,则返回 true。
boolean add(Object element);
//如果此 collection 由于调用而发生更改,则返回 true。(如果此 collection 不允许有重复元素,并且已经包含了指定的元素,则返回 false。)
Iterator iterator();
//返回在此 collection 的元素上进行迭代的迭代器。
boolean containsAll(Collection c);
//如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean addAll(Collection c);
//将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
boolean removeAll(Collection c);
//移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。此调用返回后,collection 中将不包含任何与指定 collection 相同的元素。
boolean retainAll(Collection c);
//仅保留和形参c相同的元素(取交集)。
//仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。换句话说,移除此 collection 中未包含在指定 collection 中的所有元素。
Object[] toArray();
//返回包含此 collection 中所有元素的数组。
1、Collection方法举例:
1)实现类为ArrayList
package com.hpe.container;
import java.util.ArrayList;
import java.util.Collection;
public class TestCollectionMethod {
public static void main(String[] args) {
//父类引用指向子类对象
Collection c = new ArrayList();
//可以放入不同类型的变量
c.add("hello"); //添加一个字符串
c.add(new Name("f1", "l1")); //添加一个Name对象
c.add(new Integer(100)); //只能存放对象,不能存放基本数据类型
System.out.println(c.size());
System.out.println(c); /* c调用子类ArrayList的toString()方法,该toString调用内部
每个元素自己的toString方法,用中括号括起,以逗号分隔开,
因此我们要在自定义Name类中重写toString方法。 */
}
}
class Name {
private String firstName, lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName; this.lastName = lastName;
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public String toString() { return firstName + " " + lastName; }
}
运行结果:
3
[hello, f1 l1, 100]
总结:
1)一个容器对象可以放入不同的引用数据类型数据。
2)使用父类引用指向子类对象的原因:
ArrayList是Collection的实现类,Collection是一个接口,本身所有的方法都被ArrayList这些容器类实现,那么Collection的引用在调用自己方法的时候会有多态性,即实际调用的是子类方法,如果此时要将ArrayList换成HashSet,也只要换成HashSet的构造方法即可,其它涉及多态的部分都不要变,因为父类引用调用的原ArrayList的方法,也一定都被HashSet全部实现了,不会有不兼容的问题,因此这样去写,程序的扩展性极高。
2、容器基础举例:
1)实现类为HashSet
package com.hpe.container;
import java.util.Collection;
import java.util.HashSet;
public class TestContainerBasic {
public static void main(String[] args) {
/* 父类引用指向子类对象 */
Collection c = new HashSet();
c.add("hello");
c.add(new Name("f1", "l1"));
c.add(new Integer(100));
c.remove("hello");
c.remove(new Integer(100));
System.out.println(c.remove(new Name("f1", "l1")));
System.out.println(c);
}
}
Name类位于第一个例子中:
class Name {
private String firstName, lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName; this.lastName = lastName;
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public String toString() { return firstName + " " + lastName; }
}
运行结果:
false
[f1 l1]
总结:
1)"hello"和new Integer(100)都成功remove,而Name对象却没有remove,打印了false,容器中只剩下这一个元素。
2)remove()内部会调用每个对象的equals()方法,如果与传入的对象相等,则删除对象。
3、如果两个对象equals,那么这两个对象的hashCode应该相等。
容器类对象在调用remove、contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法(集合和列表中)和hashCode方法(映射中);因此,对于自定义的类型,需要重写equals和hashCode方法以实现自定义对象的相等规则。当一个对象用在HashMap类中作为键时,会用到hashCode方法,详细分析见JavaSE_32th_容器(类集框架)。
注意:相等的对象应该具有相等的hash codes。
增加Name类的equals和hashCode方法如下:
class Name {
private String firstName, lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName; this.lastName = lastName;
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public String toString() { return firstName + " " + lastName; }
public boolean equals(Object obj) {
if(obj instanceof Name) {
Name name = (Name) obj;
return firstName.equals(name.firstName) && lastName.equals(name.lastName);
}
return super.equals(obj);
}
public int hashCode() {
return firstName.hashCode();
}
}
再次运行第二个例子:
true
[]
运行结果显示容器已经成功删掉了内部的Name对象。