目录
一.集合和数组
数组(可以存储基本数据类型)是用来存放对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用。
集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用。
二.Java集合简介
java.util提供了集合类,包括:
List,Set,Map都是接口,List,Set 两个都继承至 Collection 接口,Map 为独立接口
List:有序可重复元素集合 ArrayList LinkedList Vector
Set:无序不重复元素集合 HashSet TreeSet
Map:通过Key查找Value的映射表 HashMap TreeMap HashTable
Java集合支持范型,通过迭代器(Iterator)访问集合。
Java集合提供 Comparator 接口用来排序
Collections是操作集合的工具类
三.常用集合
1.集合常用操作
2.集合遍历
3.编写 equals 方法
接口 | 子接口 | 是否有序 | 是否允许元素重复 | 优缺点 |
Collection | 否 | |||
List(有序 可重复) | ArrayList | 是 | 是 | 优点: 底层数据结构是数组,查询快,增删慢。 缺点: 线程不安全,效率高 |
LinkedList | 是 | 是 | 优点: 底层数据结构是链表,查询慢,增删快。 缺点: 线程不安全,效率高 | |
Vector | 是 | 是 | 优点: 底层数据结构是数组,查询快,增删慢。 缺点: 线程安全,效率低 | |
Set(无序 唯一) | HashSet | 否 | 否 | |
TreeSet | 是(用二叉排序树) | 否 | ||
Map | HashMap | 否 | key必须唯一,value可以重复 | |
TreeMap | 是(用二叉排序树) | key必须唯一,value可以重复 | ||
针对Collection集合我们到底使用谁呢?(掌握)
唯一吗?
是:Set
排序吗?
是:TreeSet或LinkedHashSet
否:HashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。
否:List
要安全吗?
是:Vector
否:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。
如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。
如果你知道用集合,就用ArrayList。
1.List常用操作
List是一种有序列表,通过索引访问元素。
void add(E e) 在末尾添加一个元素
void add(int index, E e) 在指定索引添加一个元素
int remove(int index) 删除指定索引的元素
int remove(Object e) 删除某个元素
boolean contains(Object o) 判断是否包含某个元素
E get(int index) 获取指定索引的元素
int size() 包含元素的个数
indexOf(Object o) 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
boolean isEmpty() 是否为空
Object[] toArray() 将元素数组化
iterator() 返回迭代器
2.集合遍历
1.Iterator:迭代输出,是使用最多的输出方式。
2.增强for循环:
3.for循环
1.迭代器:
Iterator it=list.iterator();//创建迭代器对象
while(it.hasNext()){//循环遍历
}
2.增强for:
for(int x : a){ }
3. for循环
for(int i=0;i<list.size();i++){}
Iterator所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含以下三种方法:
1.hasNext()是否还有下一个元素。
2.next()返回下一个元素。
3.remove()删除当前元素。
3.编写equals方法
判断元素是否存在或者查找元素索引:
boolean contains(Object o) 是否包含某个元素
int indexOf(Object o) 查找某个元素的索引,不存在返回-1
要正确调用contains / indexOf方法,放入的实例要正确实现equals()equals()编写方法:
1.判断this==o
2.判断o instanceof Person
3.强制转型,并比较每个对应的字段
基本类型字段用==直接比较
引用类型字段借助Objects.equals()判断
四.Map
1.Map 简介
2.Map 常用方法
3.Map遍历
4.编写equals和hashCode
1.Map 简介
Map是一种键值映射表,可以通过Key快速查找Value
Map接口有三个比较重要的实现类,分别是HashMap、TreeMap和HashTable。
- TreeMap是有序的,HashMap和HashTable是无序的。
- Hashtable的方法是同步的,HashMap的方法不是同步的。这是两者最主要的区别。
2.Map 常用方法
V put(K key, V value):把Key-Value放入Map
V get(K key):通过Key获取Value
boolean containsKey(K key):判断Key是否存在
V remove(Object key); 删除关联对象,指定key对象
clear() 清空集合对象
boolean isEmpty() 长度为0返回true否则false
int size()
3.Map 遍历
循环Key和Value:entrySet() 推荐
循环Key:keySet()
用values()
1.entrySet()
Set<Map.Entry<String,String>> entry=maps.entrySet();
for (Map.Entry<String,String> keyValue:entry){
System.out.println(keyValue.getKey());
System.out.println(keyValue.getValue());
}
Set<Map.Entry<String,String>> es=maps.entrySet();
Iterator<Map.Entry<String,String>> it=es.iterator();
while(it.hasNext()){
Map.Entry<String,String> en=it.next();
System.out.println("key="+en.getKey()+",value="+en.getValue());
}
2.keySet()
Iterator<String> it=maps.keySet().iterator();
while (it.hasNext()) {
String key=it.next();
System.out.println("key="+key+",value="+maps.get(key));
}
3.values()
Map<String,String> maps = new HashMap<String,String>();
maps.put("key1","lisi1");
maps.put("key2","lisi2");
maps.put("key3","lisi3");
maps.put("key4","lisi4");
for (String s:maps.values()) {
//只能遍历 value 不能获取到key对象
System.out.println(s);
}
4.编写equals和hashCode
编写equals和hashCode
正确使用Map必须保证:
作为Key的对象必须正确覆写equals()方法
作为Key的对象必须正确覆写hashCode()方法
覆写hashCode:
如果两个对象相等,则两个对象的hashCode()必须相等
如果两个对象不相等,则两个对象的hashCode()尽量不相等(可以相等,会造成效率下降)
hashCode可以通过Objects.hashCode()辅助方法实现
五.集合比较器 Comparator
1.Comparable接口
2.Comparator 接口
3.Comparable接口 和 Comparator 接口区别
1.Comparable接口
Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”。
public class Student implements Comparable<Student>{
//该方法用于比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、
零或正整数.根据不同类的实现返回不同,大部分返回1,0和-1三个数
@Override
public int compareTo(Student o) {
return this.age-o.age;
}
}
Student stu1=new Student("joe",22);
Student stu2=new Student("jack",23);
int i=stu1.compareTo(stu2);
System.out.println(i);//结果返回-1
2.Comparator 接口
Comparator是比较接口。我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排序,这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过实现Comparator来新建一个比较器,然后通过这个比较器对类进行排序
Student stu1=new Student("joe",22);
Student stu2=new Student("jack",20);
List<Student> lists=new ArrayList<>();
lists.add(stu1);
lists.add(stu2);
Comparator<Student> comparator=new Comparator<Student>() {
//返回“负数”,意味着“o1比o2小”;
//返回“零”,意味着“o1等于o2”;
//返回“正数”,意味着“o1大于o2”。
//o1.getAge()-o2.getAge(); 表示增序
//o2.getAge()-o1.getAge(); 表示降序
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
}
};
Collections.sort(lists,comparator);
for (Student s:lists){
System.out.println(s);
}
3.Comparable接口 和 Comparator 接口区别
Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”。
而Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。
两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。