Java是如何存储元素的(3)—Collection集合存储数据原理

一、集合概述

(1)什么是集合?有什么用?

数组其实就是一个集合,集合实际上就是一个容器,可以来容纳其他类型的数据。

(2)集合为什么说在开发中使用较多?

集合是一个容器,是一个载体,可以一次容纳多个对象,在实际开发中,假设连接数据库,数据库当中有10条记录,那么假设把这10条记录查询出来,在java程序中会将10条数据封装成10个java对象,然后将10个java对象放到某一个集合当中,将集合传到前端,然后遍历集合,将一个数据一个数据展现出来。

(3)集合中存储的是引用

集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,集合当中存储的都是java对象的内存地址。(或者说集合中存储的是引用);

	List.add(100);//自动装箱Integer

注意:集合在java中本身是一个容器,是一个对象,集合在任何时候存储都是“引用”。

(4)在java中每一个不同的集合,底层会对应不同的数据结构,往不同的集合中存储元素,等于将数据放到了不同的数据结构当中。

二、集合结构图

(1)集合的分类

在java中集合分为两大类。一类的是Collectioin,另一类的Map

(2)Collection继承结构图

(0)List为有序,可重复,存储的元素有下标,而Set正好相反,无序、不可重复、没有下标。

(1) Iterable是一个接口,Collection这个接口继承了它,当它调用Iterable接口的时候,会返回一个Iterable这个对象,然后通过这个对象可以进行遍历。

(2)Vector底层采用数组这种数据结构。(这个是线程安全)vector所有的方法都有synchronized修饰,但是效率低,所以这个方法使用就很少。

(3)Hashset底层是HashMap,实际上HashSet集合在new的时候,底层实际上new了一个HashMap集合。向HashSet集合中存储元素,实际上是存储到HashMap集合中了。HashMap集合是一个哈希表数据结构。

(4)TreeSet集合底层实际上是TreeMap newTreeSet集合的时候,底层实际上new了一个TreeMap集合。往TreeSet集合中存放数据的时候,实际上是将数据放到TreeMap集合中了。TreeMap集合底层采用了二叉树数据结构。

(5)SortedSet特点:也是无序不可重复,但是放在它里面的元素可以自动排序。我们称为可排序的集合。放到集合中的元素是自动按照大小顺序排序的,

(3)Collection常用方法

(a)

  • boolean
  • add(E e)
  • 确保此集合包含指定的元素(可选操作)。

其实集合里面只能存放的是引用,所以1200是自动装箱,Integer x= new Integer(1200);add方法里面存放了x的地址。

(b)获取集合中元素的个数

  • int
  • size()
  • 返回此集合中的元素数。

(c)清空

 

(d) 判断集合中是否包含此元素

  • boolean
  • contains(Object o)
  • 如果此集合包含指定的元素,则返回 true 。

我们想一下,这个包含是指的内存地址还是指的是内容?下面我们通过一个例子来展示一下

        /*创建集合对象*/
        Collection c1 = new ArrayList();
        /*往集合中添加元素*/
        String s1 = new String("abc");
        c1.add(s1);
        String s2 = new String("def");
        c1.add(s2);
        String x = new String("abc");
        System.out.println(c1.contains(x));

我们现在把s1,s2两个对象放入到了c1集合里面,现在又声明了一个x对象,里面的内容和s1一样都是abc,我们现在调用c1的contains方法,判断c1.contains(x)返回true还是false。

这个的返回值是true,下面是内存图

contains里面其实是equals方法,因为String已经重新写了Equals方法,所以比较的是内容。

所以contains方法是用来判断集合中是否包含某个元素的方法。所以在底层的时候用了equals方法。

(e)删除集合中的某个元素

  • boolean
  • remove(Object o)
  • 从该集合中删除指定元素的单个实例(如果存在)(可选操作)。

 

 (g)判断该集合中的元素的个数是否为0

底层调用的size(紫色代表实例变量)

        /*创建集合对象*/
        Collection c1 = new ArrayList();
        /*往集合中添加元素*/
        String s1 = new String("abc");
        c1.add(s1);
        String s2 = new String("def");
        c1.add(s2);
        String x = new String("abc");
        c1.remove(x);
        System.out.println(c1.size());

判断现在集合里面是否还有s1?

没有了,因为remove里面也是调用了equals方法。

(f)将集合转换为数组(了解)

  • toArray()
  • 返回一个包含此集合中所有元素的数组。

 

 

 很明显这里存的是内存地址。

三、Collection集合迭代

注意:以下讲解的遍历/迭代方式,是所有Collection通用的一种方式,在Map集合中不能使用,在所有的Collection以及子类中使用。

(1)首先声明了集合

Collection c1 = new ArrayList();

(2)往集合里面添加元素

c1.add(100);
c1.add(20);
c1.add("赵晓东");

(3)拿到迭代器

 Iterator i1 = c1.iterator();

(4)对迭代器进行遍历

 while (i1.hasNext()){
            Object o1 = i1.next();
            System.out.println(o1);
        }

解释一下,迭代器有两个重要的方法,一个是hasNext()用来判断下面是否还有数据,next()是用来获取的。

四、List

(1)List集合存储元素特点

有序:List集合中的元素有下标,从0开始,从1递增。

可重复:存储一个1,还可以再存储1.

(2)List常用方法

(a)

  • get(int index)
  • 返回此列表中指定位置的元素。

 (b)在指定位置添加元素

• void    • add(int index, E element) 
    • 将指定的元素插入此列表中的指定位置(可选操作)

 

 我现在用这个方法,往指定元素中添加。

因为有下标,所以List集合有自己比较特殊的遍历方式,通过下标遍历。[List集合特有的方式,Set没有

因为有下标,所以List集合有自己比较特殊的遍历方式,通过下标遍历。[List集合特有的方式,Set没有.

(c)修改指定位置元素

  • set(int index, E element)
  • 用指定的元素(可选操作)替换此列表中指定位置的元素。

 

 (3)ArrayList

1、默认初始化容量为10

2、集合底层是Object数组

3、集合的size()方法是获取集合中元素的个数,而不是获取容量。

4、ArrayList集合的扩容

扩容到原容量的1.5倍。

ArrayList集合尽可能减少扩容

5、优点:检索效率比较高

缺点:随机增删元素效率比较低,另外数组无法存储大数据量,但是向数组末尾添加元素的效率还是很高的。

6、这么多集合中,那个集合最多?

ArrayList,因为一般都在末尾添加元素。检索效率也比较高。

(4)LinkedList

Linkedlist集合有初始化容量吗?没有,最初这个链表是没有任何元素。first和last引用都是Null,不管是likedList还是ArrayList,以后写代码时不需要关心具体哪个集合,因为我们面向接口编程,调用的方法都是接口中的方法

 五、Set

(1)HashSet集合,HashSet的遍历

        Set<String> s1 = new HashSet<>();
        s1.add("嘻嘻");
        s1.add("哈哈哈");
        s1.add("嘻嘻");
        for (String t1 :s1){
            System.out.println(t1);
        }

因为Set是不可重复的,所以存入两个“嘻嘻”,会被覆盖

(2)HashSet

        Set<String> s1 = new TreeSet<>();
        s1.add("A");
        s1.add("B");
        s1.add("D");
        s1.add("C");
        for(String t1:s1){
            System.out.println(t1);
        }
A
B
C
D

因为HashSet可以自动排序。

总结:Collection是一个接口,所以它不能声明对象,List和Set分别继承了 它,List里面有ArrayList和LinkedList还有Vector。Set有HashSet和TreeSet。他们都声明方式基本相同,遍历都是通过Iterator进行遍历,他们添加元素都是一样的,都是通过add()元素进行添加。其中List可以通过get()获取元素。然而set是没有get()方法的,这个和他们的内存有关系,其实List是有下标的,Set没有下标,这也就决定了是否有get()方法。

猜你喜欢

转载自blog.csdn.net/MyxZxd/article/details/106179154