集合框架 (一)Collection单列集合

集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,经常使用

集合体系结构:一:Collection单列集合,二:Map:双列集合

 集合框架 (一)Collection单列集合_第1张图片

Collection单列集合

每个元素(数据)只包含一个值

Collection集合体系

接口,实现类

集合特点

集合框架 (一)Collection单列集合_第2张图片

        ArrayList list = new ArrayList<>(); // 有序 可重复 有索引
        list.add("java1");
        list.add("java2");
        list.add("java1");
        list.add("java2");
        System.out.println(list);

        HashSet set = new HashSet<>(); // 无序,不重复,无索引
        set.add("java1");
        set.add("java2");
        set.add("java1");
        set.add("java2");
        set.add("java3");
        System.out.println(set);//[java3,java2,java1]

Collection集合的常用方法:所有单列集合都可以直接使用

collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的

1.public boolean add(E e):添加元素, 添加成功返回true。

collection是接口,不能new,可以用它的实现类,如ArrayList集合对象

        Collection c = new ArrayList<>(); // 多态写法
        
        c.add("java1");
        c.add("java1");
        c.add("java2");
        c.add("java3");
        System.out.println(c);//[java1,java1,java2,java3]
2.public void clear():清空集合的元素。
        c.clear();
        System.out.println(c);//输出[]
3.public boolean isEmpty():判断集合是否为空 是空返回true,反之。
如:System.out.println(c.isEmpty());
4.public int size():获取集合的大小,返回元素个数。
如:System.out.println(c.size());
5.public boolean contains(Object obj):判断集合中是否包含某个元素。
如:System.out.println(c.contains("java1")); 
6.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
如:System.out.println(c.remove("java1"));
7.public Object[] toArray():把集合转换成数组
        Object[] arr = c.toArray();
        System.out.println(Arrays.toString(arr));

        String[] arr2 = c.toArray(new String[c.size()]);//转换成指定类型数组的形式如String类型
        System.out.println(Arrays.toString(arr2));
8, addAll()方法:把一个集合的全部数据倒入到另一个集合中去。
        Collection c1 = new ArrayList<>();
        c1.add("java1");
        c1.add("java2");
        Collection c2 = new ArrayList<>();
        c2.add("java3");
        c2.add("java4");
        c1.addAll(c2); // 就是把c2集合的全部数据倒入到c1集合中去。
        System.out.println(c1);//[java1,java2,java3,java4]
        System.out.println(c2);//[java3,java4]

Collection的遍历方式:所有单列集合都可以直接使用

一,迭代器

集合框架 (一)Collection单列集合_第3张图片

public class CollectionDemo01 {
    public static void main(String[] args) {
        Collection c = new ArrayList<>();
        c.add("赵敏");
        c.add("小昭");
        c.add("素素");
        
        System.out.println(c);
        // c = [赵敏, 小昭, 素素]
                              

        // 使用迭代器遍历集合:
        Iterator it = c.iterator();

        // 1、从集合对象中获取迭代器对象。 //手工遍历,麻烦
        System.out.println(it.next());//赵敏
        System.out.println(it.next());//小昭
        System.out.println(it.next());//素素
        System.out.println(it.next());//出现异常的

        // 2、我们应该使用循环结合迭代器遍历集合。
        while (it.hasNext()){
            String ele = it.next();
            System.out.println(ele);
        }
    }
}

二,增强for

集合框架 (一)Collection单列集合_第4张图片

public class CollectionDemo02 {
    public static void main(String[] args) {
        Collection c = new ArrayList<>();
        c.add("赵敏");
        c.add("小昭");
        c.add("素素");
        c.add("灭绝");
        System.out.println(c);
        // c = [赵敏, 小昭, 素素, 灭绝]

        // 使用增强for遍历集合或者数组。
        for (String ele : c) {           //快捷方法:c.for再回车
            System.out.println(ele);
        }

        String[] names = {"迪丽热巴", "古力娜扎", "稀奇哈哈"};
        for (String name : names) {      //names.for再回车
            System.out.println(name);
        }
    }
}

三,lambda表达式

集合框架 (一)Collection单列集合_第5张图片

public class CollectionDemo03 {
    public static void main(String[] args) {
        Collection c = new ArrayList<>();
        c.add("赵敏");
        c.add("小昭");
        c.add("殷素素");
        c.add("周芷若");
        System.out.println(c);
        // [赵敏, 小昭, 殷素素, 周芷若]

        // default void forEach(Consumer action):  结合Lambda表达式遍历集合:


//        c.forEach(new Consumer() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });
//
//        c.forEach((String s) -> {
//                System.out.println(s);
//        });
//
//        c.forEach(s  -> {
//            System.out.println(s);
//        });
//
//        c.forEach(s  -> System.out.println(s) );

       
        c.forEach(System.out::println ); //简化后
    }
}

 集合中存储的是元素对象的地址

一,List集合,list是接口,不能创建list集合对象

特点,特有的方法:

特点:有序,可重复,有索引

集合框架 (一)Collection单列集合_第6张图片

public class ListTest1 {
    public static void main(String[] args) {
        // 1.创建一个ArrayList集合对象(有序、可重复、有索引)
        List list = new ArrayList<>();  // 一行经典代码
        list.add("蜘蛛精");
        list.add("至尊宝");
        list.add("至尊宝");
        list.add("牛夫人");
        System.out.println(list); // [蜘蛛精, 至尊宝, 至尊宝, 牛夫人]

        // 2.public void add(int index, E element): 在某个索引位置插入元素。
        list.add(2, "紫霞仙子");
        System.out.println(list);//[蜘蛛,至尊,紫霞,至尊,牛]

        // 3.public E remove(int index): 根据索引删除元素,返回被删除元素
        System.out.println(list.remove(2));//紫霞,,
        System.out.println(list);

        // 4.public E get(int index): 返回集合中指定位置的元素。
        System.out.println(list.get(3));

        // 5.public E set(int index, E element): 修改索引位置处的元素,修改成功后,会返回原来的数据
        System.out.println(list.set(3, "牛魔王"));//牛夫人
        System.out.println(list);
    }
}

 List集合支持的遍历方式:

1,for循环(因为list集合有索引)

2,迭代器

3,增强for循环

4,Lambda表达式

public class ListTest2 {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("糖宝宝");
        list.add("蜘蛛精");
        list.add("至尊宝");

        //(1)for循环
        for (int i = 0; i < list.size(); i++) {  //快捷:lit.fori再回车
            // i = 0 1 2
            String s = list.get(i);
            System.out.println(s);
        }

        //(2)迭代器。
        Iterator it = list.iterator();
        while (it.hasNext()) {  //it.hasNext().while回车
            System.out.println(it.next());
        }

        //(3)增强for循环(foreach遍历)
        for (String s : list) {    //list.for再回车
            System.out.println(s);
        }

        //(4)JDK 1.8开始之后的Lambda表达式
        list.forEach(s -> {         //list.forEach回车
            System.out.println(s);
        });
    }
}

1,ArrayList集合的底层原理,

基于数组实现的

数组的特点:根据索引查询数据快,删除效率低,添加效率极低

集合框架 (一)Collection单列集合_第7张图片

应用场景:

适合:根据索引查询数据,比如根据随即索引取数据(高效),或者数据量不是很大时

不适合:数据量大的同时,又要频繁对数据进行增删操作

2,LinkedList集合的底层原理,应用场景:

基于双链表实现的

集合框架 (一)Collection单列集合_第8张图片

链表的特点:查询慢,无论查询哪个数据都要从头开始找

                      链表增删相对快

双向链表特点:查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的

集合框架 (一)Collection单列集合_第9张图片

 应用场景:
1,用来设计队列

队列的特点:先进先出,后进后出

   // 1、创建一个队列。
        LinkedList queue = new LinkedList<>();
        // 入队
        queue.addLast("第1号人");
        queue.addLast("第2号人");
        queue.addLast("第3号人");
        queue.addLast("第4号人");
        System.out.println(queue);//[1,2,3,4]
        // 出队
        System.out.println(queue.removeFirst());
        System.out.println(queue.removeFirst());
        System.out.println(queue.removeFirst());
        System.out.println(queue);//[4]
2,用来设计栈 

栈的特点:后进先出,先进后出

数据进入栈模型的过程称为:压/进栈(push)

        离开                                弹/出栈(pop)

        // 2、创建一个栈对象。
        LinkedList stack = new LinkedList<>();
        // 压栈(push)
        stack.push("第1颗子弹");
        stack.push("第2颗子弹");
        stack.push("第3颗子弹");
        stack.push("第4颗子弹");
        System.out.println(stack);//[4,3,2,1]
        // 出栈(pop)
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack);//[2,1]

二,Set集合,set是接口

特点:

集合框架 (一)Collection单列集合_第10张图片

 // 1、创建一个Set集合的对象
        Set set = new HashSet<>(); // 创建了一个HashSet的集合对象 一行经典代码  HashSet: 无序 不重复 无索引
        set.add(666);
        set.add(555);
        set.add(555);
        set.add(888);
        set.add(888);
        set.add(777);
        set.add(777);
        System.out.println(set);//[888,777,666,555]       
 Set set = new LinkedHashSet<>(); //  有序 不重复 无索引
                                           //[666,555,888,777]

 Set set = new TreeSet<>(); //  可排序(升序) 不重复 无索引
                                           //[555,666,777,888]

注意:Set要用到的常用方法 ,基本上都是Collection提供的!

HsahSet集合的底层原理:

1,哈希值:

集合框架 (一)Collection单列集合_第11张图片

        Student s1 = new Student("蜘蛛精",25, 169.5);
        Student s2 = new Student("紫霞",22, 166.5);
        System.out.println(s1.hashCode());//2003749087
        System.out.println(s1.hashCode());//2003749087
        System.out.println(s2.hashCode());//1234565732

        String str1 = new String("abc");
        String str2 = new String("acD");
        System.out.println(str1.hashCode());//96354
        System.out.println(str2.hashCode());//96354

集合框架 (一)Collection单列集合_第12张图片

 jdk8之前:集合框架 (一)Collection单列集合_第13张图片

哈希表是一种增删改查数据性能都较好的结构

jdk8开始,当链表长度超过8,且数组 长度大于等于64时,自动将链表转成红黑树,进一步提高了操作数据的性能

2,数据结构(树)

二叉树:

集合框架 (一)Collection单列集合_第14张图片

集合框架 (一)Collection单列集合_第15张图片

 二叉查找树存在的问题:

当数据已经排好时,让树尽可能矮小,以此提高查数据的性能,即平衡二叉树

红黑树,就是可以自平衡的二叉树。红黑树是一种增删改查数据性能都较好的结构

3,HashSet集合去重复的机制:

默认不能对内容一样的两个不同对象去重复!

    如何让其能够实现对内容一样的两个不同对象也能去重复????

如果希望Set集合认为2个内容一样的对象是重复的,必须重写对象的hashCode()和equals()方法

快捷方法::在类中右键选Generate,点equals()and hashCode()点next next------

public class SetTest3 {
    public static void main(String[] args) {
        Set students = new HashSet<>();
        Student s1 = new Student("至尊宝", 28, 169.6);
        Student s2 = new Student("蜘蛛精", 23, 169.6);
        Student s3 = new Student("蜘蛛精", 23, 169.6);
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());//重写后,s2s3哈希值相同
        Student s4 = new Student("牛魔王", 48, 169.6);
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        System.out.println(students);//【至尊宝,蜘蛛精,牛魔王】
    }
}

LinkedHashSet集合的底层原理

有序,不重复,无索引

TreeSet集合

不重复,无索引,可排序(默认升序排序)

底层是基于红黑树实现的排序

集合框架 (一)Collection单列集合_第16张图片

集合框架 (一)Collection单列集合_第17张图片

方式二:

        // TreeSet就近选择自己自带的比较器对象进行排序
//        Set students = new TreeSet<>(new Comparator() {
//            @Override                              new Compa---然后回车
//            public int compare(Student o1, Student o2) {
//                // 需求:按照身高升序排序
//                return Double.compare(o1.getHeight() , o2.getHeight());
//            }
//        });
        Set students = new TreeSet<>(( o1,  o2) ->  Double.compare(o1.getHeight() , o2.getHeight()));
        students.add(new Student("蜘蛛精",23, 169.7));
        students.add(new Student("紫霞",22, 169.8));
        students.add(new Student("至尊宝",26, 165.5));
        students.add(new Student("牛魔王",22, 183.5));
        System.out.println(students);

三,注意事项:集合的并发修改异常问题

。使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现此错误

。由于增强for循环遍历集合就是迭代器遍历集合的简化写法,因此,使用增强for循环遍历集合,又在又同时在删除集合中的数据时,程序也会出现此错误

???怎么保证不出bug???

1,使用迭代器遍历集合,但用迭代器自己的删除方法删除数据即可

2,如果能用for循环遍历时:可以倒着遍历并删除;或者从前往后遍历,但删除元素后做i--操作

public class CollectionTest1 {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("王麻子");
        list.add("小李子");
        list.add("李爱花");
        list.add("张全蛋");
        list.add("晓李");
        list.add("李玉刚");
        System.out.println(list);
        //  [王麻子, 小李子, 李爱花, 张全蛋, 晓李, 李玉刚]

        // 需求:找出集合中全部带“李”的名字,并从集合中删除。
//        Iterator it = list.iterator();
//        while (it.hasNext()){
//            String name = it.next();
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);//会报错!!!!!!!!!!!!!

        // 使用for循环遍历集合并删除集合中带李字的名字
        //  [王麻子, 小李子, 李爱花, 张全蛋, 晓李, 李玉刚]
        //  [王麻子, 李爱花, 张全蛋, 李玉刚]
        //                                      i
//        for (int i = 0; i < list.size(); i++) {
//            String name = list.get(i);
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);输出[王麻子, 李爱花, 张全蛋, 李玉刚],有bug

        System.out.println("--------------------------------------");
        // 怎么解决呢?
        // 使用for循环遍历集合并删除集合中带李字的名字
        //  [王麻子, 小李子, 李爱花, 张全蛋, 晓李, 李玉刚]
        //  [王麻子, 张全蛋]
        //                  i
//        for (int i = 0; i < list.size(); i++) {
//            String name = list.get(i);
//            if(name.contains("李")){
//                list.remove(name);
//                i--;       //写这个就好了     方法11111!!!!!!!!!
//            }
//        }
//        System.out.println(list);


        //for循环      倒着去删除也是可以的。             方法222222222!!!!!!!


        // 需求:找出集合中全部带“李”的名字,并从集合中删除。
//        Iterator it = list.iterator();
//        while (it.hasNext()){
//            String name = it.next();
//            if(name.contains("李")){
//                // list.remove(name); // 并发修改异常的错误。
//                it.remove(); // 删除迭代器当前遍历到的数据,每删除一个数据后,相当于也在底层做了i--   方法3333333333333!!!!!!!!!
//            }
//        }
//        System.out.println(list);

        // 使用增强for循环遍历集合并删除数据,没有办法解决bug.
//        for (String name : list) {
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);
        //使用lambda表达式也没有办法解决bug
//        list.forEach(name -> {
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        });
//        System.out.println(list);
    }
}

四,Collection的其他相关知识

1,前置知识:可变参数

public class ParamTest {
    public static void main(String[] args) {
        // 特点:
        test(); // 可以不传数据
        test(10); // 可以传输一个数据给它
        test(10, 20, 30); // 可以传输多个数据给它
        test(new int[]{10, 20, 30, 40}); //可以传输一个数组给可变参数
    }

    // 注意事项1:一个形参列表中,只能有一个可变参数。
    // 注意事项2:可变参数必须放在形参列表的最后面
    public static void test(int...nums){   定义一个方法
                        可变参数类型...名称
        // 可变参数在方法内部,本质就是一个数组。
        System.out.println(nums.length);
        System.out.println(Arrays.toString(nums));
        System.out.println("--------------------------");
    }
}
//输出:
0
[]
--------------------------
1
[10]
--------------------------
3
[10,20,30]
---------------------------
4
[10,20,30,40]
---------------------------

2,Collections

是一个用来操作集合的工具类

1、public static boolean addAll(Collection c, T...elements):为集合批量添加数据

        List names = new ArrayList<>();
        Collections.addAll(names, "张三", "王五", "李四", "张麻子");
        System.out.println(names);

 2、public static void shuffle(List list):打乱List集合中的元素顺序。

       Collections.shuffle(names);
       System.out.println(names);

  3、 public static void sort(List list):对List集合中的元素进行升序排序。

        List list = new ArrayList<>();
        list.add(3);
        list.add(5);
        list.add(2);
        Collections.sort(list);
        System.out.println(list);



        List students = new ArrayList<>();
        students.add(new Student("蜘蛛精",23, 169.7));
        students.add(new Student("紫霞",22, 169.8));
        students.add(new Student("紫霞",22, 169.8));
        students.add(new Student("至尊宝",26, 165.5));
        // Collections.sort(students); 报错 解决方法:让对象的类去实现Comparable
        // System.out.println(students);
4、public static  void sort(List list, Comparator c): 对List集合中元素,按照比较器对象指定的规则进行排序
        Collections.sort(students, new Comparator() {
            @Override
            public int compare(Student o1, Student o2) {
                return Double.compare(o1.getHeight(), o2.getHeight());
            }
        });
        System.out.println(students);

3,综合案例

 斗地主游戏

集合框架 (一)Collection单列集合_第18张图片

你可能感兴趣的:(java,服务器)