- 集合:
- 继承图:
- Collection接口声明的常用方法:
- 集合新特性foreach循环遍历集合或项目:
- List接口:
- ArrayList源码分析 :
- LinkedList源码分析:
- List接口中的常用方法:
- set接口:
- HashSet:
- LinkedHashSet:
- TreeSet:
- Map结构:
- Map结构的理解:
- HashMap的底层实现原理(以jdk7为例):
- jdk8相较于jdk7在底层实现方面的不同:
- Map中的常用方法:
- TreeMap:
- Properties:
- Collections工具类的常用方法:
-
boolean add(E e):将元素添加到集合中,如果是基本数据类型会自动装箱,在集合中的都是object对象
-
boolean addAll((Collection extends E> c):将其他集合实现类对象包含的元素添加到当前对象中
-
void clear():清空当前集合实现类对象包含的元素
-
boolean isEmpty():判断集合是否为空
-
boolean contains(object o):判断当前集合实现类对象是否包含指定对象o,会调用该对象类的equals()方法,如果没有重写equals()方法,则比较的是地址值,来判断是否包含
-
boolean containsAll(Collection> c):判断形参中的所有元素是否都存在于当前集合实现类对象中
-
boolean equals(object o):判断当前集合实现类对象与指定的集合实现类对象是否相等(包含的元素一样且元素位置相同,相对于有序序列而言),同样会调用equals()方法
-
int hashCode():返回当前对象的哈希值
-
Iterator iteator():返回Iterator接口的实例,用于遍历集合元素
集合实现类对象调用Iterator()方法,返回实现Iterator接口的实现类对象,可以遍历该集合实现类对象的元素
调用接口实现类对象的next()方法,指针默认在集合第一个元素的前一个位置,每调用一次后,指针下移,(超出集合实现类对象元素个数会报错),返回该位置的元素
//遍历方式一:for(int i = 0,i < 集合对象.size(); i++) 集合对象.next() //遍历方式二:while(集合对象.hasNext()) //boolean hasNext() 集合对象.next()
Iterator接口的remove()方法(不同于集合中的remove()):删除此时指针所在位置的对象,如果还未调用next方法时调用remove()会报错(此时指针还未指向元素)或者是在上一次调用remove()方法没有调用next方法,再次调用remove()方法,那么也会报错(因为此时该指针位置上的元素已被删除)
-
default Stream:
-
Boolean remove(object o):移除当前集合实现类对象中所包含的指定元素,会调用该对象类的equals()方法,如果没有重写equals()方法,则比较的是地址值
-
default boolean removeIF(predicate super E> filter)
-
boolean retainAll(collection > c)**:在当前集合实现类对象中删去与指定集合实现类对象不一样的元素,保留一样的,同样调用equals()方法,自定义类对象要重写
-
boolean removeAll(collection> c):**从当前集合实现类对象中移除指定集合实现类所包含的所有元素
-
int size():**获取集合中元素的数量
-
default Stream stream():
-
default Spliterator spliterator()
-
object[] toArray():**将集合转换为数组
将数组转换为集合:调用Arrays类的静态方法asList()方法
List
list = Arrays.asList(new String[]{"aa","bb","cc"}) List list = Arrays.asList(new int[]{123,456})//这样写会被集合当成一个元素 List list = Arrays.asList(123,456)//两个元素 List list = Arrays.asList(new Integer[]{123,456})//两个元素 -
T[] toArray(T[] a):
内部调用的还是迭代器
for(集合对象的类型 局部变量 : 集合对象){}
例如:for(Object obj : coll){}
for(int i : arr){}
List接口:
ArrayList源码分析 :
jdk7:
ArrayList list = new ArrayList(); //底层创建了长度为10的Object[]数组elementDate
使用add()方法添加元素时,如果默认容量不足,则扩容,默认情况下,扩容为原来容量的1.5倍,同时将原数组中元素赋值到新的数组中
在开发中,尽量使用带参的构造器,指定构造器的初始容量
ArrayList list = new ArrayList(int capacity);
jdk8的变化:
ArrayList list = new ArrayList(); //底层Object[]数组elementDate初始化为{},并没有创建长度为10 的数组,而是在调用add()方法时创建
小结:
LinkedList源码分析:jdk7中ArrayList的创建类似单例的饿汉式,而jdk8中ArrayList的创建类似单例的懒汉式,延迟了数组的创建,节省内存。Vector构造器创建对象时底层都创建长度为10的数组。Vector的扩容为原来容量的2倍
LinkedList list = new LinkedList();内部声明了Node(内部类)类型的first和last属性,默认值为null.
private static class NodeList接口中的常用方法:{ E item; Node next; Node prev; Node(Node ,E element, Node next){ this.item = item; this.next = next; this.prev = prev; } }
- void add( int index, Object ele ):在index位置插入ele元素,如果放入的形参是集合,那么加入当前集合的该集合会被当成一个元素
- boolean addAll( int index, Collection eles ):从index位置开始将eles中的所有元素添加进来
- object get( int index ):获取指定index位置上的元素
- int indexOf( Object obj ):返回obj在集合首次出现的位置,元素不存在返回 -1
- int lastIndexOf( Object obj ):返回obj在集合末次出现的位置 ,元素不存在返回 -1
- Object remove( int index ):移除指定index位置的元素,并返回此元素
面试小题:List list = new ArrayList(1,2,3); list.remove(2); //删除的是数据3 删除2 :list.remove(new Integer(2)) 区分于Collection接口中的remove(Object obj)
- Object set( int index, Object ele ):设置指定index位置的元素ele
- List subList( int fromIndex, int toIndex ):**返回从fromIndex到toIndex位置的子集合
无序性:
不等于随机性,根据Hashcode进行散列确定在底层数组的存储位置,可以通过迭代器遍历
不可重复性:
如果存在哈希冲突,使用分离链表法,比较元素的hash值,如果hash值相同(虚拟地址相同),再调用元素所在类的equlas()(根据需求考虑是否重写),equals()方法返回true,添加失败,false,添加成功
set散列分离链表法:
jdk7:新元素放入数组中,指向原来的元素
jdk8:原来的元素在数组中,指向新的元素
set接口中没有额外定义新的方法,使用都是Collection中声明过的方法
要求:
LinkedHashSet:向Set中添加的数据,其所在类一定要重写hashCode()和equals()
重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码
LinkedHashSet作为HashSet子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据的前一个和后一个元素的位置,对于频繁的遍历操作,有较高的效率
TreeSet:底层采用红黑树的存储结构
向TreeSet中添加的数据要求是相同类的对象
两种排序方式:自然排序(自定义类实现comparable接口) and 定制排序(自定义类实现comparator接口)
自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals()(定制排序也一样),且添加的元素不能重复,若想添加同一个类有个别属性相同,总体不同的对象,在自然排序时,使用嵌套比较该属性
Map结构: Map结构的理解:若要对TreeSet对象使用自然排序,则自定义类实现comparable接口即可(非自定义类不用),若要对TreeSet对象使用定制排序,则创建comparator接口的实现类对象,作为TreeSet构造器的参数。
Map中的key:无序的、不可重复的,使用Set存储所有的key —>key所在的类要重写equals()和hashCode()(以HashMap为例)
Map中的value:无序的、可重复的,使用Collection存储所有的value
一个键值对:key-value构成一个Entry对象
Map中的entry:无序的、不可重复的,使用set存储所有的entry
HashMap的底层实现原理(以jdk7为例):HashMap map = new HashMap();
在实例化以后,底层创建了长度是16的一维数组Entry[] table
map.put(key, value):
首先调用key所在的类的hashCode(),计算key的哈希值,经过某种算法计算后,得到在Entry数组中的存放位置。如果该位置上为空,则添加成功。若不为空,此时该位置上的元素以链表的形式存在,将key依次与该位置上的元素比较,比较方式是调用key所在类的hashCode()方法,若与该位置上的所有元素都比较后哈希值均不同,则添加成功,若相同,则继续比较:调用value所在类的equals()方法,若与所有key哈希值相同的元素比较equals()后都不同,则添加成功,若出现相同则使用新添加的key对应的value替换原来key对应的value
在不断的添加过程中,会涉及到扩容问题,当超出底层数组临界值,且要存放的位置非空时,扩容,扩容后重新对集合中的所有元素计算扩容后在数组中的位置
默认的扩容方式:扩容为原来容量的2倍,并将原有的数据赋值过来
jdk8相较于jdk7在底层实现方面的不同:-
new HashMap():底层没有创建长度为16的数组
-
jdk8底层的数组是:node[] ,而不是Entry[]
-
首次使用put()方法时,底层创建长度为16的数组
-
jdk7底层结构只有:数组+链表。 jdk8底层结构:数组+链表+红黑树
当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8,且当前数组的长度 > 64时,此时该索引位置上的所有数据改为使用红黑树存储
Map中的常用方法:HashMap的默认容量:16
HashMap的默认加载因子:0.75
Bucket中链表长度大于默认值转化红黑树:8
桶中的Node被树化时最小的hash表容量:64
元素修改和删除方法:
-
Object put() :将指定键值对添加到(或修改)key-value当前map对象中
-
void putAll(Map m) :将指定的map对象中的元素存放到当前map中
-
Object remove(Object key):移除指定的key的key-value对,并返回该key对应的value,如果该key不存在,返回null
-
void clear():清空当前map中的所有值
元素查询方法:
-
Object get(Object key):获取指定key对应的value
-
boolean containsKey(Object key): 当前map对象是否包含指定的key
-
boolean containsValue(Object value):当前map对象是否包含指定的value
-
int size():
-
boolean isEmpty():
-
boolean equals(Object obj):判断当前map与指定的map对象是否相等
原视图操作的方法:不能用iteator遍历map
-
Set keySet():返回所有key构成的Set集合
-
Collection values():返回所有value构成的Collection集合
-
Set entrySet():返回所有key-value对构成的Set集合
Map.Entry是一个内部接口
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
Map.Entry entry = (Map.Entry) obj;
//map.Entry接口中定义的有getKey()和getValue()方法
Systen.out.println(entry.getKey() + entry.getValue())
}
TreeMap:
使用与TreeSet一致(包括自然排序与定制排序的使用)。
Properties:常用来处理配置文件。key和value都是String类型的
Collections工具类的常用方法:


