集合的概述
- 为了保存一些数目不明确的对象,jdk中提供了一系列特殊的类,这些类可以存储任意类型的对象,并且长度可变,统称为集合。
- 集合分为两大类单列集合Collection和双列集合Map
Collection接口
Collection是所有单列集合的父接口
添加功能(掌握)
boolean add(Object obj):
boolean addAll(Collection c):
删除功能(掌握)
void clear():
boolean remove(Object obj):
boolean removeAll(Collection c):
判断功能(掌握)
boolean isEmpty():
boolean contains(Object obj):
boolean containsAll(Collection c):
遍历功能(掌握)
Iterator iterator():
长度功能(掌握)
int size():
交集功能
boolean retainAll(Collection c):
转换功能
Object[] toArray():
List接口
- ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高
- Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低
- LinkedList:底层数据结构是链表,查询慢,增删快,线程不安全,效率高
- List特有功能:List的特有功能
添加功能
void add(int index,Object obj):
删除功能
Object remove(int index):
修改功能
Object set(int index,Object obj):
获取功能
Object get(int index):
int indexOf(Object obj):
ListIterator listIterator():
set接口
- HashSet:底层数据结构是哈希表。如何保证元素唯一性呢?依赖两个方法。hashCode()和equals()。以后都自动生成。
- TreeSet:底层数据结构是二叉树。如何保证元素唯一性呢?如何保证元素排序呢?根据返回值是否是0,判断元素是否重复。排序有两种方案:元素具备比较性 实现Comparable接口。集合具备比较性 实现Comparator接口
Map接口
- HashMap:如果对象的成员变量值都相同,我们则认为是同一个对象。
- TreeMap:如果对象的成员变量值都相同,我们则认为是同一个对象。同时,我们还要按照年龄排序。
泛型
- 泛型类:
- 泛型接口
- 泛型方法
- 泛型的作用:将运行时期可能出现的错误提前到编译时期,借鉴了数组,提前给定了类型,避免了强制转换。
Hash和Tree写入对象是需要注意的事项
通过HashSet的add()方法我们发现如果对自定义对象去重,我们需要重新hashCode和equals俩方法
equals方法重写步骤
public boolean equals(Object obj){
//提高效率
//提高健壮性
//内容比较,严谨点的话对引用类型也做非null判断
}
@Override
public boolean equals(Object obj) {
System.out.println(this + "----------" + obj);
//提供性能
if(obj == this){
return true;
}
//提供健壮性
if(!(obj instanceof Student)){
return false;
}
Student s = (Student)obj;
if(s.name != null){
if(this.name.equals(s.name)){
if(this.age == s.age){
return true;
}
}
}
return false;
}
hashCode方法重写步骤
public int hashCode(){
return 所有的成员变量之和;
//引用类型使用其hashCode值,基本数据类型直接相加即可
//为了提高效率,使用基本数据类型随意乘上1个数,
//这样的话完全不一样的对象重复的几率较低,不用比较equals方法,性能略高
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.name.hashCode() + this.age * 13;
}
TreeSet有两种方法,一是对象实现comparable接口并重写compareTo方法,二是创建一个比较器对象,比较器对象中实现comparator接口并重写compare方法,在创建TreeSet对象时比较器对象
作为参数传递或者参数使用匿名内部类
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
//按照姓名的长度进行排序
int num = this.name.length() - o.name.length();
//按照年龄进行排序
num = (num == 0) ? this.age - o.age : num;
//按照姓名的字典顺序
num = (num == 0) ? this.name.compareTo(o.name) : num;
return num;
}
public class MyComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
//按照姓名的长度进行排序
int num = o1.getName().length() - o2.getName().length();
//按照年龄进行排序
num = (num == 0) ? o1.getAge() - o2.getAge() : num;
//按照姓名的字典顺序
num = (num == 0) ? o1.getName().compareTo(o2.getName()) : num;
return num;
}
}
//创建比较器对象
//MyComparator mc = new MyComparator();
//创建集合对象
//new 接口(){};相当于创建了一个实现这个接口的子类对象
//new 类(){};相当于创建了一个继承了这个类的子类对象
TreeSet<Student> ts = new TreeSet<Student>(
new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//只按照年龄进行排序
return o1.getAge() - o2.getAge();
}
}
);