集合,IO,多线程
反射,注解,泛型
jvm
Collection和Map
Collection:包括List和Set。List:有序,可重复;Set:无序,不可重复
有序:存入顺序和取出顺序一致
方法:查增删改
一.List接口:
1.ArrayList(可变数组)
(1)内部封装了一个数组,查找(随机访问)块,增删慢
(2)方法:查:get(i) 增加:add(i,e),add(e) 删除:remove(i),remove(e) 改:set(i,e)
size(),isEmpty(),toArray()
数组和集合的互相转化(主要是与List的转换,与Set也可以)
//1.数组转集合(包装数组转集合,如果是基本数组,则需要先遍历一遍,转为包装数组,再转为集合) Integer[] arr=new Integer[] {1,2,3}; List<Integer> list=new ArrayList<>(Arrays.asList(arr)); //2.集合转数组(用toArray(T[] a)方法) Integer[] array=list.toArray(new Integer[0]);
//基本类型数组与包装类型数组的转换:就用for循环吧
java8的Stream流得看看
2.LinkedList
(1)内部是:双向循环链表(有头尾指针:first和last),增删快,查找慢
(2)方法:查、增、删
查:getFirst(),getLast(),get(i) 增:addFirst(),addLast(),add(i,e),add(e) 删:removeFirst(),removeLast(),remove(i),remove(e) 。remove()
3.Collection集合遍历
(1)foreach遍历集合
for(元素类型 临时变量 : 容器){
}
只能查找(访问),不能增删改
(2)Iterator遍历集合
用Iterator遍历时,如果要删除元素,要用迭代器自身的删除方法
Collection,Map用于存储元素,Iterator用于遍历。内部采用指针的方式跟踪集合中的元素,开始指向第一个元素之前
使用Iterator对集合元素迭代时,如果调用了集合对象的remove()方法去删除元素,会出现异常。原因是:集合中删除了元素会导致迭代器预期的迭代次数发生改变,导致迭代器的结果不准确。可以使用迭代器自身的删除方法。
二.Queue接口
1.Deque接口
(1)ArrayDeque 可以用作栈,队列(单端队列,双端队列) 比LinkedList块
(2)LinkedList
2.PriorityQueue优先级队列
三.Set接口:
1.HashSet
(1)当向HashSet添加一个元素时,index=hashCode(key)%tableSize,
首先会调用该元素的hashCode()方法来确定元素的存储位置,然后调用equals()方法来确保该位置没有重复元素
(2)为了正常工作,需要重写存入对象的equals()方法和hashCode()方法(重写equals方法必须重写hashCode方法),不重写,不能保证唯一性
两个对象相同,hashCode一定相同;hashCode相同,这两个对象不一定相同
(3)方法:
查:contains(e) 增:add(e) 删:remove(e)
size(),isEmpt()
(4)没有get()方法
2.TreeSet
(1)内部用红黑树存储元素。保证没有重复元素,并且可以对元素排序
(2)两种排序方式:自然排序和定制排序
四.Map接口:
Map接口中定义了一些增删改查的方法
LinkedHashMap保证元素存入和取出的顺序
1.HashMap
(1)存的是键值对entry,键和值允许为空,但键不能重复。且集合中元素无序
(2)底层有哈希表结构组成,其实就是:数组+链表+红黑树。故HashMap对元素的增删改查效率比较高
(3)方法:查:get(key) 增:put(key,value) 删:remove(key) 改:replace(key,value)
大小:size(),判空:isEmpty() 判断:containsKey(key),containsValue(value)
获取键值对集:Set entrySet()---getKey(),getValue() 获取键集:Set keySet() 获取值集:Collection values()
2.TreeMap(可以排序)
3.Map集合遍历
(1)Iterator遍历:两种:keySet(),entrySet()
(2)forEach()遍历
四.常用工具类:
1.Collections工具类
2.Arrays工具类
细节:
1.HashSet
(1)HashSet添加元素时,首先会调用该元素的hashCode()方法来确定元素的存储位置,然后再调用元素对象的equals()方法来确保该位置没有重复元素
(2)当向集合中存入元素时,为了保证HashSet正常工作,要求在存入对象是,需要重写Object类中的hashCode()和equals()方法。
存入字符串时,String类已经默认重写了hashCode()和equals()方法。但如果自定义的类型对象存入HashSet,就不能保证不可重复性。出现这种情况是因为自定义类型没有重写hashCode()和equals()方法
(3)HashSet底层是new了一个HashMap,其元素是内部map的key;所有key所对应的值都是一个静态的Object对象
(4)HashCode就像人的名字。两个对象的hashCode一样,两个对象可能一样;但如果hashCode不一样,那么肯定不是同一个对象。相当于先确定一个大的范围,再用equals去比较
equals()相等的两个对象他们的hashCode一定相等,也就是equals对比是绝对可靠的。hashCode相等的两个对象他们的equals不一定相等,也就是hashCode不是绝对可靠的
2.TreeSet
(1)集合中元素在进行比较时,都会调用compareTo()方法,该方法是Comparable接口中定义的,因此要想对集合中的元素进行排序,就必须实现Comparable接口。java中大部分类都实现了Coparable接口,并默认实现了接口中的copareTo()方法,如包装类,String等。自定义类型数据无法直接在集合中排序,java提供了两种排序规则:自然排序,定制排序。默认情况下,TreeSet都采用自然排序
(2)自然排序,集合中元素实现了Comparable接口,集合会对该元素使用compareTo()方法进行比较,并默认进行升序排序
(3)定制排序,在创建TreeSet集合时就自定义一个比较器来对元素进行定制排序
方法:创建TreeSet集合时传入Comparator接口实现类参数 / 传入Lambda表达式参数
3.HashMap
(1)哈希表结构中,水平方向数组的长度称为HashMap的容量(capacity),竖直方向每个元素位置对应的链表结构称为一个桶(bucket),每个桶的位置在集合中都有对应的桶值,用于快速定位集合元素的添加,查找时的位置
(2)链表添加元素是头插法(为了插入更快,不用遍历)
(3)HashMap根据具体情况,动态的分配桶数量。创建时,默认集合容量capacity=16,加载因子loadFactor=0.75,此时阈值threshold=capacity*loadFactor=12.
不断添加元素,超过12个时,集合默认新增加一倍桶的数量到32
(4)LinkedHashMap可以保证元素的添加顺序
4.TreeMap
(1)TreeMap同TreeSet一样,也可以通过自定义比较器Comparator对所有键进行定制排序
序:
1.LinkedList用作链表
头插:addFirst() 尾插:addLast() 中间插:add(int index,E element) 都无返回值
头删:removeFirst() 尾删:removeLast() 中间删:remove(index) 返回值都是Object
查头:getFirst() 查尾:getLast() 查中间:get(int index)
2.LinkedList用作栈
栈方法 等效方法
入栈 push(e) addFirst(e)
出栈 pop() removeFirst()
取栈顶元素 peek() peekFirst()
3.LinkedList用作单端队列
队列方法 等效方法
入队 offer(e) addLast(e) 区别:前者返回boolean,后者返回void
访问队头 peek() getFirst()
出队 poll() removeFirst()
4.排序:comparable接口和comparator比较器
5.遍历