Java单列集合

目录

一、Collection集合

1、Collection集合概述

2、Collection集合的三种遍历方式

(1)迭代器遍历

(2)增强for遍历

(3)lambda表达式

二、List集合

1、概述与特有方法

2、List的五种遍历方式

(1)迭代器

(2)列表迭代器

(3)增强for遍历

(4)lambda表达式

(5)普通for循环

3、List底层原理

(1)ArrayList

(2)LinkedList

(3)迭代器

三、Set集合

1、Set集合概述

2、HashSet

(1)哈希值

(2)对象的哈希值

3、LinkedHashSet

4、TreeSet

(1)概述

(2)Comparator

(3)两种比较方式小结

(4)两种方式中关于返回值的规则

四、总结


一、Collection集合

1、Collection集合概述

Collection是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现

方法名说明
boolean add(E e)添加元素
boolean remove(Object o)从集合中移除指定的元素
boolean removeIf(Object o)根据条件进行移除
void clear()清空集合中的元素
boolean contains(Object o)判断集合中是否存在指定的元素
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中元素的个数

创建Collection集合的对象可使用多态的方式,有具体的实现类ArrayList

2、Collection集合的三种遍历方式

(1)迭代器遍历

java中迭代器是集合专用的遍历方式。

e.g.

public class IteratorDemo1 {
    public static void main(String[] args) {
        //创建集合对象
        Collection<String> c = new ArrayList<>();

        //添加元素
        c.add("hello");
        c.add("world");
        c.add("java");
        c.add("javaee");

        //Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
        Iterator<String> it = c.iterator();

        //用while循环改进元素的判断和获取
        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
    }
}

迭代器中的删除

//void remove(): 删除迭代器对象当前指向的元素
public class IteratorDemo2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("b");
        list.add("c");
        list.add("d");

        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String s = it.next();
            if("b".equals(s)){
                //指向谁,那么此时就删除谁.
                it.remove();
            }
        }
        System.out.println(list);
    }
}

(2)增强for遍历

增强for遍历的内部原理就是一个Iterator迭代器,是为了简化迭代器的代码书写的。

实现Iterable接口的类才可以使用迭代器和增强for。

单列集合和数组才能用增强for遍历。

for(String str : list){
            System.out.println(str);
        }

细节:修改增强for中的变量不会改变集合中原有的数据。

           迭代器遍历完毕,指针不会复位。

           循环中只能用一次next方法。

           迭代器遍历时,不能用集合的方法进行增加或者删除。

(3)lambda表达式

public static void main(String[] args) {
       /* 
        lambda表达式遍历:
                default void forEach(Consumer<? super T> action):
        */

        //1.创建集合并添加元素
        Collection<String> coll = new ArrayList<>();
        coll.add("zhangsan");
        coll.add("lisi");
        coll.add("wangwu");
        //2.利用匿名内部类的形式
        //底层原理:
        //其实也会自己遍历集合,依次得到每一个元素
        //把得到的每一个元素,传递给下面的accept方法
        //s依次表示集合中的每一个数据
       /* coll.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

        //lambda表达式
        coll.forEach(s -> System.out.println(s));
    }

二、List集合

1、概述与特有方法

有序,存和取的元素顺序一致。
有索引,用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
可重复,与Set集合不同,列表通常允许重复的元素

Collection有的方法List都实现了继承。

List特有方法:

方法名描述
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素

2、List的五种遍历方式

(1)迭代器

Iterator<String> it = list.iterator();
     while(it.hasNext()){
        String str = it.next();
        System.out.println(str);
}

(2)列表迭代器

ListIterator<String> it = list.listIterator();
while(it.hasNext()){
    String str = it.next();
    if("bbb".equals(str)){
        //qqq
        it.add("qqq");
    }
}

(3)增强for遍历

 for (String s : list) {
       System.out.println(s);
   }

(4)lambda表达式

list.forEach(s->System.out.println(s) );

(5)普通for循环

for (int i = 0; i < list.size(); i++) {
        String s = list.get(i);
        System.out.println(s);
}

3、List底层原理

(1)ArrayList

核心步骤:

1. 创建ArrayList对象的时候,底层先创建了一个长度为0的数组。

   数组名字:elementDate,定义变量size。

   size这个变量有两层含义:
   ①:元素的个数,也就是集合的长度
   ②:下一个元素的存入位置

2. 添加元素,添加完毕后,size++

扩容时机一:

3. 当存满时候,会创建一个新的数组,新数组的长度,是原来的1.5倍,也就是长度为15.再把所有的元素,全拷贝到新数组中。如果继续添加数据,这个长度为15的数组也满了,那么下次还会继续扩容,还是1.5倍。

扩容时机二:

4. 如果一次添加多个元素,1.5倍放不下,那么新创建数组的长度以实际为准。

(2)LinkedList

1. 刚开始创建的时候,底层创建了两个变量:一个记录头结点first,一个记录尾结点last,默认为null
2. 添加第一个元素时,底层创建一个结点对象,first和last都记录这个结点的地址值
3. 添加第二个元素时,底层创建一个结点对象,第一个结点会记录第二个结点的地址值,last会记录新结点的地址值

(3)迭代器

* Iterator<E> iterator()  :获取一个迭代器对象

* boolean hasNext()       :判断当前指向的位置是否有元素

* E next()                :获取当前指向的元素并移动指针

三、Set集合

1、Set集合概述

无序,存与取顺序不一致

不重复,可以将重复元素去除

无索引,不能使用普通for循环遍历,也不能通过索引获取元素,没有使用索引的方法

继承自Collection,其功能均可继承使用。

2、HashSet

存取无序
不可以存储重复元素

(1)哈希值

哈希值是根据hashCode方法算出的int类型整数,该方法定义在Objcet类中,默认使用地址值进行计算。一般情况下会将hashcode方法重写,利用对象内部的属性值来计算哈希值。

(2)对象的哈希值

如果没有重写hashCode方法,不同对象计算出的哈希值并不相同,如果重写过hashCode方法,只要属性值相同,不同对象计算出的哈希值也是相同的。

哈希碰撞:有的时候不同属性值或者不同地址值计算出的哈希值也可能一样。

int index = (数组长度 -1) & 哈希值

如果集合中存储的是自定义对象,则必须要重写hashCode和equals方法。

在jdk8以后,当链表长度超过8,数组长度大于等于64时,会自动转换成红黑树。

3、LinkedHashSet

有序、不重复、无索引

LinkedHashSet底层源于哈希表,使用双链表记录和添加。

如果要进行数据去重,先使用HashSet,如果要求又要去重又要存取有序,再使用LinkedHashSet。

4、TreeSet

(1)概述

不重复、无索引、可排序

默认按照由小到大排序

TreeSet底层源于红黑树的数据结构来进行排序,增删改查性能较优。

TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator) :根据指定的比较器进行排序

对于数值类型(Integer、Double)默认按照从小到大顺序排序。

对于字符字符串类型,按照ASCII码表中的数字升序进行排序。

(2)Comparator

1、使用空参构造创建TreeSet集合。用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的

2、自定义的Student类实现Comparable接口。自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法

3、重写接口中的compareTo方法。重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

(3)两种比较方式小结

自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序

比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序

在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排序

(4)两种方式中关于返回值的规则

如果返回值为负数,表示当前存入的元素是较小值,存左边

如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存

如果返回值为正数,表示当前存入的元素是较大值,存右边

四、总结

1、如果需要集合中元素可重复:使用ArrayList集合,基于数组。

2、如果需要集合中元素可重复,且增删操作明显多余查询:使用LinkedList集合,基于链表。

3、如果需要对集合中元素进行去重:使用HashSet集合,基于哈希表。

4、如果需要对集合中元素进行去重,且需要保证存取顺序:使用LinkedHashSet集合,基于哈希表和双链表,但效率要低于HashSet。

5、如果需要对集合中元素进行排序:使用TreeSet集合,基于红黑树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值