1.JAVA中的集合分为两大类型,一种是collection类型,一种是map(键值对形式,其中键不可重复)类型,其中collection类型又分为set(无序不重复),list(有序可重复),queue(队列类型)
2.collection中的通用方法:
boolean add(Object obj):添加一个元素
boolean addAll(Collection c):将c中的元素全部添加到集合中
void clear():清空集合中的元素
boolean contains(Object obj):判断几何中是否包括obj
boolean containsAll(Collection c):判断集合中是否包含c里的所有元素
boolean isEnpty():判断集合是否为空
Iterator iterator():返回一个迭代器对象
boolean remove(Object obj):删除指定元素,如果集合中有多个则只删除第一个
boolaen removeAll(Object obj):删除集合中所有指定元素
boolean retainAll(Collection c):删除c里不包括的元素(相当于变成与c的交集),如果集合发生改变则返回true
Object[] toArray():把集合变成数组
3.Java8为Iteraror增加了一个forEach(Consumer action)方法,其中Consumer是一个函数式接口,所以可以传入lambda表达式来简化代码:
public class CollectionEach{
public static void main(String args[]){
Collection c = new HashSet();
c.add("haha");
c.add("hehe");
c.add("heihei");
c.forEach(obj->System.out.println("迭代元素为:" + obj))
}
}
4.Iterator提供的遍历方法:
bollean hasNext():判断是否还有下一个元素
Object next():返回下一个元素
void remove():删除上一次next方法返回的元素
void forEachRemaining(Consumer action):Java8为Iterator新增的默认方法,当调用这个方法时程序会依次把集合元素传为Consumer的accept(T t)方法,这个方法也是Consummer中的唯一抽象方法,用lambda表达式重写的也是这个方法
5.Iterator必须依附于一个Collection对象,有一个Iterator对象则必然有一个与之关联的Collection对象供其操作,使用迭代器操作元素时,他只是接收到一个Collection传来的副本,本不是实际变量,使用迭代器访问元素,Collection元素不能被改变,否则会引发ModificationException异常
6.java8为Collection接口提供了一个removeIf(Predicate filter)方法,这个方法用于批量删除元素,程序会删除满足filter条件的元素,相当于一个过滤器,Predicate也是一个函数式接口,因此可以使用lambda来操作
//省略重复代码
Collection c = new HashSet();
c.add(1);
c.add(2);
c.add(3);
c.add(4);
c.add(5);
c.removeIf(ele->(Integer)ele.parseInt < 3);
System.out.println(c) //3,4,5
7.Predicate的test方法可以判断元素是否满足要求
//省略重复代码
Predicate p = obj -> (String)obj.length < 5
p.test("aaaa") //true
p.test("aaaaa") //false
8.HashSet是Set中的经典实现,也是最常使用的,HashSet按哈希算法来储存元素,所以提供了良好的存取和查找,他的特点是,无序的,存入顺序与存取数据可能不同,他还是不同步的,元素值可以为null,当存入一个对象时,他会调用对象的hashCode()方法获得哈希值,并以此来决定存储位置,HashSet判断两个对象是否相等是先通过equals()方法,来比较,在用hashCode方法,如果都相同,则视为同一个对象
9.前面说的,如果两个对象的哈希值相同,但是equals方法返回false也是可以都被存入HashSet中的,HashSet会根据哈希值作为地址储存,如果两个对象哈希值一样,则会在同一个哈希地址使用链式储存,这样会导致性能下降,因该避免,在写一个类的时候,如果重写了equals方法,则也应该重写hashCode方法,当equals方法判断两个对象相等时,应该使两个对象hashCode不相等
10.当程序把一个可变的对象存放到HashCode中事务,尽量避免修改这个对象,使这个对象等于其他重发对象,这样会把HashCode打乱,无法正常操作HashCode
11.LinkedHashSet是HashSet的子类,他也是使用哈希值来计算储存位置,但他会使用一个链式来维护储存顺序,保证遍历时是有序的,所以他的性能比HashSet低,但是他在迭代时效率会更高
12.TreeSet是SortedSet的实现,他可以确保集合中的元素是以排序的状态储存的,他比HashSet多提供了如下方法:
Comparator comparator():如果TreeSet采用了排序规则,则返回排序规则,否则返回null
Object lower():返回位于指定元素之前的元素(参数可以是集合之外的元素)
Object higher():同上,返回后一个
Object first():返回第一个
Object last():返回最后一个
SortedSet subSet(Object fromElement,Object toElement):返回fromElement(包括)到toElement(不包括)元素
SortedSet headSet(Object toElement):返回小于toElement的子集
SortedSet tailSet(Object fromElement):返回大于等于fromElement的子集
13.当把一个对象存入自然派需要的TreeSet集合中,那么这个对象必须实现了Comparaable接口,这个接口中有一个方法compareTo(Object obj),TreeSet会调用这个方法来比较两个元素的大小(0相等<也就不能被储存>,正数大于,负数小于),如果要使用TreeSet,要保证自己写的对象的equals方法与compareTo方法返回的结果一致
14.同HashSet一样,不要修改集合中的可变对象
15.要使用TreeSet的定制排序,可以在实例TreeSet时传入一个Comparator接口,这也是一个函数式接口,可以使用lambda替代
他接受两个Object类型的变量,返回正数,0或者负数,返回的数值作用也是正数大负数小0相等
16.List是一个有序的集合,他会根据你插入元素的顺序来分配索引,并通过索引来访问元素,LIst判断两个对象是否相等是通过equals方法例如下面的代码
class A{
public boolean equals(Object obj){
return true;
}
}
public class Test{
public static void main(String args[]){
List l = new ArrayList()
l.add("haha");
l.add("hehe");
l.add("lala");
//l.removeAll(new A());执行这条会把集合清空
l.remove(new A()); //会删除第一个元素
l.remove(new A()); //会删除的二哥元素
}
}
17.与Set不同,java为List集合提供了一个ListIterator接口,他是Iterator的子接口,他可以实现向前迭代
18.ArrayList和Vector作为List的经典实现,被使用的频率是最多的,他们是基于数组来派生的,他们会有一个成员变量,initialCapacity来确定集合的长度,当存储的元素超过这个长度之后,他会自动增加,他的默认值为10,当如果确定要用ArrayList或者Vector存储很大容量的数据时,应该手动设置长度,避免让他自己自增,这样会减少系统开销提升程序性能
19.Vector作为比较古老的类,其中大多数的方法都过时了,他跟ArrayList相比唯一的优势就是他是线程安全的,但在多线程编程中也不推荐使用它,因为JAVA8提供了Collections包,里面有很多工具类可以是ArrayList变为线程安全的,Vector有一个子类Stack,他是一个栈结构的(后进先出),他也是比较古老的,当需要使用栈结构时,有更好的ArrayDeque,因此,也不推荐使用
20.Queue是一个队列类型的集合,通常不允许访问其中的随机元素,只可以向末尾添加,操作头部元素,它提供了以下方法:
void add(Object obj):向末尾添加
Object element():获取头部元素,但不删除
boolean offer(Object e);和add方法相似,但当使用有容量限制的队列,效果要更好
Object peek();获取头部元素,但不删除,队列为空返回null
Object poll():获取头部元素,并删除,队列为空返回null
Object remove():获取头部元素,并删除
21.Deque是Queue的子接口,他代表一个双端队列(因此也可以实现栈模式),ArrayDeque是Deque的经典实现类,当想把一个ArrayDeque当作栈来使用,就使用push()添加,pop()删除,当作队列使用就offer()添加,poll()删除
22.LinkedList是List的另一个实现,她还是实现了Deque接口,所以它也可以作为队列或者栈来使用,他与ArrayList,ArrayDeque实现的机制不同,他不是通过数组来实现的,他是基于链模式,因此,他在访问随机元素上比Array.....要差一些,但是他在插入,删除速度上,表现要更好
23.对于遍历数组元素,在遍历Array....时,尽量使用get()方法,而非迭代器,(因为底层使用数组实现),在遍历LinkedList时就要使用迭代器了
24.Map中是以键值对储存的,每一个Key都能找到对应的Value,Key不可重复,但是value可以,Map存储Key的方式与Set有惊人的相似,就连名字都是(Hash,LinkHash,Tree.....),从源码上来看,java是先实现了一个Map,然后通过把这个Map所有的Key的Value变为null,就实现Set(可见Map与Set的关系多么密切)
25.Map中包含一个内部类Entry,每一个Entry用于保存一组键值对,还有很便捷的方法(getKey,getValue,setValue)
26.HashMap与Hashtable(从名字就可以看出她有多古老,连java命名规范都没实现)的关系就好像ArrayList于Vector的关系(一新一老,一安全一不安全,一快一慢),其中一点不同是HashTable不允许使用null来为key,value赋值
27,HashMap判断key是否相等的方法与Set一致,通过equals和hashCode,判断value是否相等就只考虑equals
28.Hashtable有一个子类被广泛使用Proterties,它是用来处理属性相关文件的,他的key,value都必须是String类型
29.WeakHashMap与HashMap基本相似,不同的HashMap保存的是实际引用(强引用,就是说HashMap不被销毁,那么他存储的所有对象都不会被回收),WeakHashMap保存的是弱引用(当保存的对象没有别的引用指向时可能被回收,也可能被删除)
30.IdentityHashMap与HashMap大致相同,不同的是他判断key是否相等会使用obj1 == obj2的方式,这好像是有意违反Map的机制
31.Java9新增的of方法可以创建不可变类,例如List l = List.of("haha","hehe"),Set s = Set.of("lala","bobo")