一、基本类型
容器类就是保存对象,划分为两个不同概念:
1)Collection:一个独立元素的序列,List必须按照插入的顺序保存元素,Set不能有重复元素,Queue按照排队规则确定对象产生顺序
2)Map:键值对,允许通过键来查找值.ArrayList允许使用数字来查找值
Collections是[java.util]下的类,它包含有各种有关集合操作的静态方法。
Collection是个[java.util]下的接口,它是各种集合结构的父接口。
分类概述:
List :ArrayList LinkedList
Set : HashSet(最快获取元素的方法) TreeSet(升序保存结果) LinkedHashSet(按照被添加顺序保存)
Map : HashMap(最快的查询) TreeMap(升序保存键) LinkedHashMap(按照插入顺序保存 保留查询速度)
二、List
2.1 List继承Collection接口
a.有序
b.有索引
c.允许存储重复元素
2.2ArrayList 数组结构 非同步
随机访问效率高,但插入和删除性能较低
class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, Serializable
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
System.out.println(list);
结果:[a, b, c, a] --add()默认在0位置插入元素
list.add(3,"wutong");
System.out.println(list);
结果:[a, b, c, wutong, a]
String removeStr = list.remove(3);
System.out.println(removeStr); //
结果:wutong --remove返回删除的元素
String setStr = list.set(0, "A");
System.out.println(setStr);
结果:a set()返回之前指定位置的元素
System.out.println(list);
结果:[A, b, c, a]
//遍历list的三种方式:
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
for (String s : list) {
System.out.println(s);
}
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
list在for循环遍历中删除元素会发生java.util.ConcurrentModificationException
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("g");
for (String s : list) {
if (s.equals("b")){
list.remove(s);
}
}
--会发生如下异常:
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at com.wu.tong.container.demo01.DemoList.test02(DemoList.java:72)
需要用迭代器方式遍历才可以:
public void test02(){
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("g");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if (next.equals("b")){
iterator.remove();
}
}
System.out.println(list);
}
结果:[a, c, g]
2.3LinkedList 链表结构 非同步
查询慢,增删快
public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, Serializable {
LinkedList还添加了可以使用其用作栈,队列,双端队列的方法:
getFirst() element()返回列表的第一个元素而不移除,如果List为空,则抛出NoSuchElementException,peek()在列表为空时返回null
removeFirst() remove()移除并返回列表的头,如果列表为空,则抛出NoSuchElementException,poll()在列表为空时返回null
addFirst() add() addLast()都将某个元素插入到列表的尾端
removeLast()移除并返回列表的最后一个元素
LinkedList<String> linked = new LinkedList<>();
linked.add("a");
linked.add("b");
System.out.println(linked);
linked.push("tong");
System.out.println(linked);
结果:
[a, b, c]
[tong, a, b, c]
add()方法是从队尾插入,相当于addLast(); push()方式是从队头插入,相当于addFirst()
2.4迭代器
Iterator
(1)使用方法iterator()要求容器放回一个Iterator,Iterator将准备好返回序列的第一个元素
(2)使用next()获得序列中的下一个元素
(3)使用hasnext()检查序列中是否还有元素
(4)使用remove()将迭代器新近返回的元素删除
ListIterator是一个更大强大的Iterator的子类型,只能用于各种List的访问。双向移动
hasNext() hasPreviouse()
2.5Stack LIFO 后进先出
Stack使用LinkedList实现的
push() 接受对象, peek() pop()将返回对象 ,peek返回栈顶元素 pop移除并返回栈顶元素
2.6Queue FIFO
offer() 将一个元素插入队尾,
peek() element() 都将在不移除的情况下返回对头,但是peek在队列为空时返回null,而element会抛出NosuchElementException异常。
poll() remove()移除并返回对头,但是poll在队列为空时返回null,而remove会抛出NosuchElementException异常。
2.7PriorityQueue 优先级队列(内部用堆(见六小节)实现)
PriorityQueue调用offer方法来插入对象时,这个对象会在队列中被排序
三、Set
继承Collection接口
1.不允许包含重复元素[重写hashcode和equals方法]
2.没有索引
2.1HashSet 内部实现是HashMap
哈希表结构(查询快),无序,非同步
哈希值:对象的逻辑地址
哈希值不相等 对象肯定不相等;哈希值相等 对象不一定相等
jdk1.8之前 哈希表= 数组+链表
之后 哈希表=数组+链表[长度<=8]
哈希表=数组+红黑树[长度>8]
HashSet 为快速查找而设计的set,存入hashSet的元素必须定义hashcode
treeSet 保持次序的Set,底层为树结构,元素必须实现Comparable
LinkedHashSet 具有hashSet的查询速度
查找是set最重要的操作,HashSet对快速查找进行有优化
HastSet输出顺序无规律可言,这是因为出于速度原因的考虑,HashSet使用了散列。
TreeSet将元素存储在红-黑树数据结构中,而HashSet使用的是散列函数
TreeSet的构造器传入String.CASE_INSENTIVE_ORDER按照字母排序
散列与散列码:
存储一组䛾最快的数据结构就是数组,所以用它来表示键的信息。但是因为数组不能调整容量,
数组并不保存键本身,而是通过键对象生成一个数字,将其作为数组的下标,这数字就是散列码
2.2LinkedHastSet
有序set
多一条链表维护存储顺序
四、Collections
Collections.addAll(list,"f","g","h","i","j");
Collections.shuffle(list);
Collections.sort(list, new Comparator() {}
Comparable 自己和参数比较 compareTo方法
Comparator 找第三方比较两个参数 compare方法
五、Map
HashMap:Map基于散列表的实现。插入和查询键值对的开销是固定的
LinkedHashMap:类似于HashMap,但是迭代遍历时,取得键值对的顺序是插入顺序
TreeMap:基于红黑树的实现,查看键或者键值对时,会被排序(次序由Comparable或Comparator决定)
map的遍历方式:
private static void show() {
Map<String, Integer> map = new HashMap<>();
map.put("鼠", 1);
map.put("牛", 2);
map.put("虎", 3);
System.out.println(map);
System.out.println("--------01----------");
Set<String> str = map.keySet();
for (String s : str) {
System.out.println(s + " = " + map.get(s));
}
System.out.println("--------02---------");
Iterator<String> iterator = str.iterator();
while (iterator.hasNext()) {
String key = iterator.next();
Integer integer = map.get(key);
System.out.println(key + "= " + integer);
}
System.out.println("--------03---------");
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> me : entries) {
System.out.println(me.getKey() + " = " + me.getValue());
}
}
六、堆
完全二叉树【不要求最后一层是满的,但如果不满,则要求所有节点必须集中在最左边,从左到右是连续的,中间不能有空的】
满二叉树【除了最后一层外,每个节点都有两个孩子,而最后一层都是叶子节点,都没孩子】
满二叉树一定是完全二叉树
完全二叉树:给定任意节点,可以根据宾浩直接快速计算出其父节点和孩子节点的编号。
存储数组,节省空间,访问效率高【对比TeeeMap】
排序二叉树完全有序,每个节点有确定的前驱和后继,不能有重复元素。
堆可以有重复元素,元素间不是完全有序,但对于父子节点之间,有一定的顺序要求。根据顺序可以分为最大堆和最小堆:
1)最大堆 :每个节点都不大于其父节点
1)最小堆 :每个节点都不小于其父节点
七、用途
java容器类库的用途是"保存对象",Collection都可以用foreach语法遍历
添加元素:
可以在Collection中添加一组元素,
Arrays.asList()方法接受一个数组或是一个用逗号分隔的元素列表,并将其转化为一个List对象
Collections.addAll()方法接受一个Collection对象,以及一个数组或者用逗号分隔的列表,将元素添加到Collection中
Collection.addAll()方法只能接受另一个Collection对象作为参数,Arrays.asList和Collections.addAll()都可使用可变参数列表
List<Integer> ll = Arrays.asList(16,17,18,19);
ll.set(0, 99);
ll.add(21);//运行时错误 不支持的操作
Arrays.asList 其实底层表示的是数组,不能调整尺寸