Java集合_Connection接口(List子接口(ArrayList&LinkedList&Vector实现类区别)、Set子接口(HashSet&TreeSet实现类区别))源码剖析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zxdspaopao/article/details/101153953

       前面重点说的差不多了,今天讲讲集合中关于Connection接口中的常用List子接口和Set子接口吧,权当自己复习过程了,自己在梳理一遍,有空闲读者也试试这种方式,整个知识的体系架构就在脑海里了存着了,今天先说到这那么开始今天的主题吧。

Connection

1、Connection接口以及常用子接口的概述。

|---Collection接口:存储的是一个一个的数据
      |----List接口:存储的是序的、可重复的数据     ----"动态"数组
            |---ArrayList、LinkedList、Vector
      |----Set接口:存储的是无序的、不可重复的数据   ----高中的"集合"
            |---HashSet、LinkedHashSet、TreeSet

简单给个图示吧:

2.Collection接口常用方法:
add(Object obj);  //添加一个对象
addAll(Collection coll1);   //添加一个Collection
size();  //集合大小
isEmpty();   //集合是否为空
clear();   //清空集合
constains(Object obj);constainsAll(Collection coll1);  //是否包含一个对象/collection
remove(Object obj);    //删除一个对象
removeAll(Colllection coll1);   //删除一个collection
equals(Object obj);hashCode();toArray();    //常用就不说了
iterator();  //获取迭代器

3.Collection集合与数组间的转换

        //toArray():集合转换为数组
        Object[] array = coll.toArray();
        System.out.println(Arrays.toString(array));
        
        //Arrays的asList(T ... t):数组转换为集合
        Collection list1 = Arrays.asList(new String[]{"AA","BB","CC"});
        System.out.println(list1);

注意:向Collection中添加的对象,要求对象所属的类一定要重写equals()。

 Iterator

1.遍历Collection的两种方式:
  方式一:使用迭代器:Iterator
  方式二:增强for循环:foreach
2.java.utils包下定义的迭代器接口:Iterator
   2.1说明:Iterator对象称为迭代器(设计模式的一种)
   2.2作用:主要用于遍历 Collection 集合中的元素。
   2.3如何获取实例:
        //iterator():返回一个迭代器的实例
   2.4常用方法:       

//hasNext():判断是否还下一个元素
//next():①指针下移 ②将下移以后集合位置上的元素返回

   2.5举例:

Iterator iterator = coll.iterator();
//hasNext():判断是否还下一个元素
while(iterator.hasNext()){
    //next():①指针下移 ②将下移以后集合位置上的元素返回
    System.out.println(iterator.next());
}

   2.6图示说明:

   

List接口(Collection子接口)

1. 存储的数据特点:存储的是有序的、可重复的数据     ----"动态"数组
2. 常用方法:
增:add(Object obj)
删:remove(Object obj) / remove(int index)
改:set(int index, Object ele)
查:get(int index)
插:add(int index, Object ele)
长度:size()
遍历:iterator() / 增强for / 一般的for

3. 常用实现类:
|----List接口:存储的是序的、可重复的数据     ----"动态"数组
|---ArrayList:主要实现类;线程不安全的,效率高;底层使用Object[]存储。
                          (Collections工具中提供了将ArrayList转换为线程安全的方法)
|---LinkedList:对于频繁的插入和删除操作,建议使用此类,因为效率高;底层使用双向链表实现。
|---Vector:古老实现类;线程安全的,效率低;底层使用Object[]存储。

4、源码剖析(***)

ArrayList的源码:

jdk7: 当添加第11个元素时,需要考虑扩容:默认扩容为原来的1.5倍,同时需要将原有数组中的数据拷贝到新的数组中。

List list = new ArrayList();//elementData = new Object[10];
list.add(1);//elementData[0] = 1;

jdk8:当我们添加第11个元素时,需要考虑扩容:默认扩容为原来的1.5倍,同时需要将原有数组中的数据拷贝到新的数组中。

List list = new ArrayList();//elementData = {}
list.add(1);//此时才创建了长度为10的Object数组,同时将元素添加到索引为0的数组位置。

所以建议使用带参数的构造器,指明底层数组的长度。避免了不必要的扩容和数组元素的复制。
比如:ArrayList list = new ArrayList(30);

Vector的源码分析:

jdk7、8:(太古老,不常用)

List list = new Vector();//elementData = new Object[10];
list.add(1);//elementData[0] = 1;

new Vector():底层创建了长度为10的数组
当添加数据到底层数组中,发现数组长度不够时,默认扩容为原来的两倍。

LinkedList的源码分析:

LinkedList list = new LinkedList();//底层用链表实现,不用考虑扩容问题
list.add(1);//在底层会将1封装在Node对象中。

Node声明为:
	private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;
    }

三者的使用:

        在大量的插入、删除时用LinkedList时效率较高,在查询修改时用ArrayList时效率较高。也就是它们底层实现的区别啦,也就是数组与链表的区别。这个我在链表那篇文章有写的。

Set接口(Collection子接口)

1. 存储的数据特点:
存储的是无序的、不可重复的数据。

①无序性:不等同于随机性。 人认为:"添加的顺序与遍历的顺序不一致,则称为无序性!"。这个观点是错误的。所谓的无序性,指的是添加数据时,不是依次紧密排列的。
②不可重复性:添加到Set中的元素是不可重复的。 参考标准:需要调用元素所在类的equals()。
2. 元素添加过程
 向Set中添加元素a,首先调用元素a所在类的hashCode()方法,计算此对象a的哈希值1,哈希值1经过某种算法以后得到哈希值2.
 此哈希值2经过某种算法,得到其在底层数组中存储的索引位置i。判断数组索引位置i上,是否元素。
      -->如果索引i位置上没元素:此元素a直接添加成功   ----情况1
      -->如果索引i位置上元素b:判断元素a和元素b哈希值2是否相等。
           -->如果哈希值不相等:元素a添加成功   ----情况2
           -->如果哈希值相等,此时调用元素a所在类的equals(),判断返回值。
                -->返回false:元素a添加成功   ----情况3
                -->返回true:元素a添加失败

Set在开发中的主要作用:用来去除重复数据。
3. 常用方法
Set在继承Collection基础上,没额外的定义方法。
4. 常用实现类:
|---HashSet:主要实现类;底层使用的数组结构
        |---LinkedHashSet:HashSet的子类;底层使用的数组结构+链表;
                            可以照添加元素的顺序实现遍历
|---TreeSet:底层使用的红黑树实现的;实现照添加的元素的指定的属性实现遍历

5. 存储对象所在类的要求:

  • 向HashSet\LinkedHashSet中添加的元素,要求其所在的类一定要重写equals()和hashCode()。
  • 向TreeSet中添加的元素,要求对象一定指明是自然排序还是定制排序。需要重写compareTo()或compare()方法。这两个方法就是判断两个对象是否相同的唯一标准。

6. TreeSet的使用:
6.1 使用说明:
  ①向TreeSet中添加的数据,必须是同一个类创建的对象。
  ②向TreeSet中添加的数据,需要指明排序方式:①自然排序  ②定制排序
  ③TreeSet中判断两个元素是否相同的标准不是考虑所在的的hashCode()和equals()了。
         而是根据排序方式中重写的compareTo() 或 compare()方法的返回值进行判断。
         如果方法的返回值为0,则认为两个对象相同。

6.2 常用的排序方式:(这个有讲了,在java常用类有讲过这两者的使用以及区别)
①自然排序  
②定制排序

猜你喜欢

转载自blog.csdn.net/zxdspaopao/article/details/101153953