栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java集合部分小结(含源码分析)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java集合部分小结(含源码分析)

文章目录
  • 集合:
        • 继承图:
        • Collection接口声明的常用方法:
        • 集合新特性foreach循环遍历集合或项目:
        • List接口:
          • ArrayList源码分析 :
          • LinkedList源码分析:
          • List接口中的常用方法:
        • set接口:
          • HashSet:
          • LinkedHashSet:
          • TreeSet:
        • Map结构:
          • Map结构的理解:
          • HashMap的底层实现原理(以jdk7为例):
            • jdk8相较于jdk7在底层实现方面的不同:
          • Map中的常用方法:
          • TreeMap:
          • Properties:
        • Collections工具类的常用方法:

集合: 继承图:

Collection接口声明的常用方法:
  • boolean add(E e):将元素添加到集合中,如果是基本数据类型会自动装箱,在集合中的都是object对象

  • boolean addAll((Collection 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 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):

集合新特性foreach循环遍历集合或项目:

内部调用的还是迭代器

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()方法时创建

小结:

jdk7中ArrayList的创建类似单例的饿汉式,而jdk8中ArrayList的创建类似单例的懒汉式,延迟了数组的创建,节省内存。Vector构造器创建对象时底层都创建长度为10的数组。Vector的扩容为原来容量的2倍

LinkedList源码分析:

LinkedList list = new LinkedList();内部声明了Node(内部类)类型的first和last属性,默认值为null.

private static class Node{
	E item;
	Node next;
	Node prev;
	
	Node(Node,E element, Node next){
		this.item = item;
		this.next = next;
		this.prev = prev;
	}
}
List接口中的常用方法:
  • 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位置的子集合
set接口: HashSet:

无序性:

不等于随机性,根据Hashcode进行散列确定在底层数组的存储位置,可以通过迭代器遍历

不可重复性:

如果存在哈希冲突,使用分离链表法,比较元素的hash值,如果hash值相同(虚拟地址相同),再调用元素所在类的equlas()(根据需求考虑是否重写),equals()方法返回true,添加失败,false,添加成功

set散列分离链表法:

jdk7:新元素放入数组中,指向原来的元素
jdk8:原来的元素在数组中,指向新的元素

set接口中没有额外定义新的方法,使用都是Collection中声明过的方法

要求:

向Set中添加的数据,其所在类一定要重写hashCode()和equals()
重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码

LinkedHashSet:

LinkedHashSet作为HashSet子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据的前一个和后一个元素的位置,对于频繁的遍历操作,有较高的效率

TreeSet:

底层采用红黑树的存储结构

向TreeSet中添加的数据要求是相同类的对象

两种排序方式:自然排序(自定义类实现comparable接口) and 定制排序(自定义类实现comparator接口)

自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals()(定制排序也一样),且添加的元素不能重复,若想添加同一个类有个别属性相同,总体不同的对象,在自然排序时,使用嵌套比较该属性

若要对TreeSet对象使用自然排序,则自定义类实现comparable接口即可(非自定义类不用),若要对TreeSet对象使用定制排序,则创建comparator接口的实现类对象,作为TreeSet构造器的参数。

Map结构: Map结构的理解:

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在底层实现方面的不同:
  1. new HashMap():底层没有创建长度为16的数组

  2. jdk8底层的数组是:node[] ,而不是Entry[]

  3. 首次使用put()方法时,底层创建长度为16的数组

  4. jdk7底层结构只有:数组+链表。 jdk8底层结构:数组+链表+红黑树

    当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8,且当前数组的长度 > 64时,此时该索引位置上的所有数据改为使用红黑树存储

HashMap的默认容量:16

HashMap的默认加载因子:0.75

Bucket中链表长度大于默认值转化红黑树:8

桶中的Node被树化时最小的hash表容量:64

Map中的常用方法:

​元素修改和删除方法:

  • 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工具类的常用方法:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/851847.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号