- 集合
- Collection
- 关于contains()和remove():
- 迭代器
- List
- ArrayList
- LinkedList
- 泛型
- Map
- Map.Entry
集合
- 集合不能直接存储基本数据类型,另外集合也不能直接村粗Java对象,存储的都是Java对象的内存地址(引用)。
- Java的集合分为两大类:
- 以单个方式存储的元素,这一类集合中的超级父接口:Collection
- 以键值对方式存储元素,这一类集合中超级父接口:Map
Collection
常用类继承结构概览:
Collection中常用方法:
- boolean add(Object e)
- int size()
- void clear()
- boolean isEmpty()
- Object[] toArray()
- boolean remove()
- boolean contains(Object e)
关于contains()和remove():
要使用这两个函数,在函数底层调用的是对象的equals()方法进行比较,因此集合中的对象应该重写equals()这个方法。
迭代器
- Iterator iterator():返回一个迭代器对象
使用迭代器来遍历集合,不用根据下标一个个遍历,for each就是一个迭代器原理
迭代器对所有Collection通用,因为Iterable是Collection的父接口
Collection c=new ArrayList();
Iterator it=c.iterator();
迭代器方法:
- boolean hasNext(),判断迭代器后一位是否有对象可以迭代
- next():迭代器向后走一位并返回元素
if(it.hasNext()){
Object o=it.next();
}
当集合结构发生改变时:必须重新获取迭代器,否则会出现异常
因此,在迭代过程中不能调用collection.remove(),但是可以调用iterator.remove(),通过迭代器对象来改变集合元素是没问题的。
List
常用方法:
- void add(int index,E element)
- E get(int index)
- E remove(int index)
- E set(int index,E element)
- int indexOf(E element)
ArrayList
集合底层是一个数组结构的对象
ArrayList对象的扩容:是重新建一个更大的对象,然后将就对象中的内容拷贝过去,因此对于ArrayList可以做的优化就是在最初创建的时候就给一个合适的大小,尽量减少底层扩容的次数
LinkedList
底层是一个双向链表
泛型
用泛型指定只能存储的类型List<String> list=new ArrayList<>();
Map
Map<K,V>常用方法
- void clear()
- boolean containsKey(Object key)
- boolean containsValue(Object value)
- V get(Object key)
- V put(K key,V value)
- V remove(Object key)
- int size()
- Set keySet()
返回Key的Set集合 - Collection values()
返回Value的集合 - Set<Map.Entry<K,V>> entryset()
返回以<Key,Value>节点作为集合元素的Set集合
Map.Entry<K,V>和Node<K,V>
Map底层中存储的对象是一个Key和value结合的节点对象,Node<K,V>
Node<K,V>:
两个属性:key 和value
两个方法: getKey()、getValue
Map.entrySet()返回的就是以Map.Entry<K,V>作为对象的Set集合,Map.Entry<K,V>就是一个Node<K,V>
HashMap:
HashMap底层是一个哈希表/散列表,
哈希表是一个数组和链表结合的结构,首先是是一个node<k,v>[]数组,下面是node<k,v>的链表。
node<k,v>的一个结构是:
node<k,v>{
final K key;
V value;
final int hash;//哈希值
node<k,v> next;//志向下一个node
}
每一个node对象都有一个确定的哈希值,根据hashnode()方法得出。
HashMap的put的实现原理:
- 底层调用hashnode()算出hash值,然后通过hash算法将hash值转换成数组下标
- 如果下标位置上无任何元素,那么添加Node上去,如果有,将k和链表上每一个node进行equals比较,若所有比较结果为False,则将Node添加到链尾。
因此,如果HashMap中放置的自定义类型,得重写hashnode()和equals()方法。
HashMap构造
HashMap 是一种常用的数据结构,一般用来做数据字典或者 Hash 查找的容器。普通青年一般会这么初始化:
HashMap<String, String> map = new HashMap<String, String>();
map.put(“name”, “test”);
map.put(“age”, “20”);
看完这段代码,很多人都会觉得这么写太啰嗦了,文艺青年一般这么来了:
HashMap<String, String> map = new HashMap<String, String>() {
{
put(“name”, “test”);
put(“age”, “20”);
}
};
TreeMap
底层结构是红黑树,节点node有五个属性(key,value,left,right,parent),节点有自身Kv和指向相关节点的引用。
TreeMap中的key根据排序规则可以进行排序形成红黑树,因此存放的对象必须可以比较,实现排序规则,有两种方式:
- 对象实现comparable接口并实现compareTo方法
Class Student implement Comparable<Student>{
private String name;
@Override
public int compareTo(Student s){
return this.name.compareTo(s.name);
}
}
- 第二种实在构造TreeMap的时候传一个比较器对象
TreeMap<Student> students=new TreeMap<>(new Comparator<Student>(){
public int compare(Student s1,Student s2){
return s1.name.compareTo(s2.name);
}
});
两种方式的比较:
在比较规则不经常发生改变时,一般实现comparable接口,若比较规则有多个或经常改变,一般使用传比较器对象的方式。
Collections集合工具类
常用方法:
- Collections.synchronizedList(List list):将List变成线程安全
- Collections.sort(List list):对list进行排序,元素必须有比较器。