集合单列(Collection)

本文详细介绍了Java集合框架中的Collection接口及其常用方法,包括迭代器、增强for循环和forEach方法的遍历方式。同时,对list系列集合如ArrayList和LinkedList的特点进行了分析,探讨了Set系列集合的底层原理,如HashSet、LinkedHashSet和TreeSet,并讲解了哈希值、哈希表结构以及如何实现排序和定制排序规则。
摘要由CSDN通过智能技术生成

集合:是存储数据的容器。

 

 Collection接口:集合体系的根接口。

         Collection的常用方法:

/**
 * 所有单列集合都是Collection接口的实现类,所有以下的方法所有的集合都能够调用。
 */
public class Demo2 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();

        //1.add(E e): 添加元素
        list.add("孙悟空");
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("猪八戒");
        list.add("沙和尚");
        list.add("白龙马");
        list.add("唐僧");

        //2.remove(E e) 删除集合中的第一个相同的元素
        list.remove("孙悟空");
        System.out.println(list);
        //3.removeif(E e)
        list.removeIf(s -> s.equals("猪八戒"));
        System.out.println(list);

        //4.contains(Object obj) 判断集合中是否包含某一个元素
        System.out.println(list.contains("白龙马"));

        //5.isEmpty() 判断集合是否为空(长度为0表示为空)
        list.isEmpty();

        //6.size() 获取集合的元素个数
        System.out.println(list.size());

        //7.toArray() 把集合容器转换为数组容器
        list.toArray();
        System.out.println(list);

        //8.clear()清空集合中的元素
        list.clear();
        System.out.println(list);
    }
}

        Collection集合的遍历方式:

                        方式一:迭代器:

/**
 * 迭代器遍历
 */
public class Demo3 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙和尚");
        list.add("小白龙");
        list.add("小白龙");
        //迭代器遍历集合(有无索引无影响,通用遍历方式)

        //1.返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引。
        Iterator<String> it = list.iterator();

        //2.询问当前位置是否有元素存在。
        while (it.hasNext()){
            //3.获取当前位置的元素,同时将迭代器对象移到下一个位置,注意防止取出越界。
            System.out.println(it.next());
        }
    }

                        方式二:增强for循环:

本质上就是迭代器。

/**
 * 增强for遍历
 * for(元素数据类型 变量名:数组/集合){
 *     ...
 * }
 */
public class Demo4 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙和尚");
        list.add("小白龙");
        list.add("小白龙");
        int[] arr={10,23,56};

        //增强for遍历:既可以遍历集合,也可以遍历数组。
        for (String s : list) {
            System.out.println(s);
        }

        for (int i : arr) {
            System.out.println(i);
        }
    }
}

 注意:迭代器遍历集合有一个问题(并发修改异常)。

        使用迭代器遍历集合时,集合自己不能对添加,删除元素,否则会出现

 

                        方式三:forEach方法遍历(结合lambda遍历集合):

/**
 * forEach方法遍历集合
 */
public class Demo6 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙和尚");
        list.add("小白龙");
        list.add("小白龙");

        /**
         * forEach方法底层会自己遍历集合,获取到每一个元素,然后把元素交给Consumer接口的实现类对象的accept方法
         * 对于accept方法拿着元素去干什么,由我们调用者决定。
         */
//        list.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s+"123");
//            }
//        });
        //调用forEach方法遍历集合
        list.forEach(s -> System.out.println(s+"123"));
    }
}

        list系列集合(有索引):

public class Demo1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙和尚");
        list.add("小白龙");
        list.add("小白龙");

        //1.add(index,element):在指定位置插入元素。
        list.add(0,"白骨精");
        System.out.println(list);

        //2.remove(index):删除指定索引处的元素。
        String removed=list.remove(1);
        System.out.println(removed);

        //3.set(index,element):修改指定索引的元素。
        list.set(0,"如来");
        System.out.println(list);

        //4.get(index)返回指定索引的元素
        System.out.println(list.get(0));
    }
}

注意:ArrayList和LinkedList都可以使用上面的方法。

        ArrayLIst底层是由数组实现的。(数组是一种查询快,增删慢的模型)

        LinkedList集合底层是一个双向链表,一个元素对应一个节点。(链表是一种查询慢,增删快的模型)

/**
 * LinkedList集合的特有方法
 */
public class Demo2 {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");

        //1.添加头节点元素
        list.addFirst("hello");
        //2.添加尾节点元素
        list.addLast("Workld");
        //3.获取头节点元素
        System.out.println(list.getFirst());
        //4.获取尾节点元素
        System.out.println(list.getLast());
        //5.删除头节点元素
        System.out.println(list.removeFirst());
        //6.删除尾节点元素
        System.out.println(list.removeLast());
    }
}

 LinkedList集合多了一些针对头和尾操作的方法。

Set系列的集合:

    

哈希值:哈希值是一个与地址值相关联的整数,任何一个对象都有哈希值。

        在Object类中有一个hashCode()方法,任何一个对象都可以调用hashCode()方法获取哈希值。

         注意:一个类不复写hashCode方法,这个类的每个对象的哈希值都不一样。

                   一个类复写了hashCode方法,这个类的对象只要属性值一样,那么哈希值就一样。

        HashSet集合底层原理:

HashSet底层是:数组+链表组成(哈希表结构)

JDK8版本后是:数组+链表+红黑树组成的(哈希表结构)

 步骤:

  1. 创建一个默认长度16的数组,数组名table
  2. 根据元素的哈希值跟数组的长度求余数计算出应该存入的位置。(哈希算法)
  3. 判断存入位置是否为null,如果为null则直接存入。如果不为null,说明这个位置有元素,需要使用equals进一步判断。
  4. 如果equals判断不同,则以链表的形式插入元素。如果相同,则认为是同一个元素,不存入。
  5.   当一个位置的元素个数超过了8个,会自动转成红黑树存储。进一步提高操作数据的性能。

 注意:如果希望Set集合认为2个内容相同的对象是重复的怎么办?

                重写对象的hashCode和equals方法。

         LinkedHashSet底层原理:

有序,不重复,无索引。

原理:底层数据结构依然是哈希表,只是每个元素又额外地多了一个双链表的机制记录存储的顺序。

 

        TreeSet集合底层原理:

TreeSet集合特点:

                1.可排序,不重复,无索引

                2.底层基于红黑树实现排序,增删改查性能较好

                红黑树是二叉排序树的一种。

                二叉排序树:由一个一个的节点组成,每一个节点有两个子节点,左边的节点都比自己小,右边的节点都比自己大。

                规则:

                        小的存左边

                        大的存右边

                        一样的不存

 TreeSet指定排序规则(默认排序)

        在源代码中,比如String,Integer,Double等,本身就是实现了Comparable接口,编写了默认排序规则。所以这些类型的元素,只要往TreeSet集合中存储就会自动排序。

        但是,存储自定义类型的元素(比如Student对象),就必须手动让Student类实现Comparable接口,复写compareto方法。

 

 

         排序原理:TreeSet调用add方法时,底层会自动调用Comparable实现类对象compareTo方法,将添加的元素和集合中已有的元素进行比较,根据compareTo方法的返回值是正数,负数,或者0,来决定谁大谁小,从而将添加的元素放在正确的位置。

TreeSet指定排序规则(比较器排序)

        在创建TreeSet集合时,可以传递一个Compatator接口的实现类对象(称为比较器),此时TreeSet集合优先使用比较器排序,如果没有比较器,再使用默认排序。

        

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值