Java进阶九—数组问题(集合框架)

Java进阶九—数组问题(集合框架)

一.原生数组带来的问题

  • 原生数组容易造成超出边界,如果非要使用传统的数组,增删改查,就要用到数据结构,非常复杂
  • CRUD是指在做计算处理时的增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete)几个单词的首字母简写
    package com.array;
    
    import org.junit.Test;
    
    public class ArrayTest {
    
        public static final int SIZE = 3;
    
        @Test
        public void testArray() {
    
            int[] array = new int[SIZE];
    
            array[0] = 1;
            array[1] = 2;
            array[2] = 3;
            array[3] = 4;
    
            for (int arrays :array) {
                System.out.println(arrays);
            }
        }
    }
    

    Java进阶九—数组问题(集合框架)_第1张图片

由此我们抛出Java Conllections FrameWork即Java集合框架,也可称为函数库 

二.Conllections家族 

  • Java集合框架是一个包含一系列实作可重复使用集合的数据结构的类别和界面集合
  • Java集合大致可以分为两大体系,一个是Collection,另一个是Map

 Java进阶九—数组问题(集合框架)_第2张图片Java进阶九—数组问题(集合框架)_第3张图片

三. 黑帮的帮规 

集合 (Java Platform SE 8) (oracle.com)

Java进阶九—数组问题(集合框架)_第4张图片

  • lterables集合层次结构中的根接口,可以理解为保护伞
  • 一般黑老大不会自己出手,会让手下三个组织来办事,所以用的时候找类来实现
  • 黑老大定下的规矩(方法),手下三个组织必须遵守。其实就是Collection的方法,实现的三个接口List,Queue,Set必须重写方法。Java进阶九—数组问题(集合框架)_第5张图片Java进阶九—数组问题(集合框架)_第6张图片

 四.ArrayList

 ArrayList (Java Platform SE 8 ) (oracle.com)

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。

ArrayList 继承了 AbstractList ,并实现了 List 接口可以自动扩容

 1.添加

这个E代表泛型,表示任意变量类型。 

public void arrayListTest() {

        // 任意类型
        ArrayList arrayList = new ArrayList();

        arrayList.add(1);
        arrayList.add(4.3);
        arrayList.add("C");
        arrayList.add("fuck");

        System.out.println(arrayList);

        // 规定为String类型,泛型限定
        ArrayList arrayList1 = new ArrayList<>();

        arrayList1.add("fu");
        arrayList1.add("ck");

        System.out.println(arrayList1);


    }

 Java进阶九—数组问题(集合框架)_第7张图片

泛型也可以是对象,创建一个Student类 

package com.array;

public class Student {
    
    private String name;

    private int age;

    public Student() {
        
    }

    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 public void arrayListTest() {

        // 泛型为Student
        ArrayList arrayList = new ArrayList<>();

        arrayList.add(new Student("fuck",22));
        arrayList.add(new Student("LiLi",33));

        System.out.println(arrayList);


    }

Java进阶九—数组问题(集合框架)_第8张图片

 

还有一种添加可以指定下标位置。 

  public void arrayListTest() {

        // 泛型为整数与浮点数时要使用他们的包装类
        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(3);

        // 添加下标时,要注意添加的位置,添加的位置已有的位置前或中间,不能是后面。
        arrayList.add(0,0);
        arrayList.add(2,2);

        System.out.println(arrayList);

    }

Java进阶九—数组问题(集合框架)_第9张图片

2.合并 Java进阶九—数组问题(集合框架)_第10张图片

  public void arrayListTest() {

        // 泛型为整数与浮点数时要使用他们的包装类
        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(3);

        // 添加下标时,要注意添加的位置,添加的位置已有的位置前或中间,不能是后面。
        arrayList.add(0,0);
        arrayList.add(2,2);

        ArrayList arrayList1 = new ArrayList<>();

        arrayList1.add(4);

        // 将arrayList1合并到arrayList
        arrayList.addAll(arrayList1);

        System.out.println(arrayList);

    }

Java进阶九—数组问题(集合框架)_第11张图片

 它是如何实现的,看源码Java进阶九—数组问题(集合框架)_第12张图片

集合转换成普通数组,拷贝数组并返回。 

第二种是选择下标插入,非常简单与添加使用的方式一样,我应该不用说了。

3.将集合转换成数组

public void arrayListTest() {

        // 泛型为整数与浮点数时要使用他们的包装类
        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);

        // 需要Object类型的数组去接收
        Object[] array = arrayList.toArray();
        
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }

    }

Java进阶九—数组问题(集合框架)_第13张图片Java进阶九—数组问题(集合框架)_第14张图片

4.清空与拷贝 Java进阶九—数组问题(集合框架)_第15张图片

 public void arrayListTest() {

        // 泛型为整数与浮点数时要使用他们的包装类
        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);

        System.out.println(arrayList);

        // 清空
        arrayList.clear();
        System.out.println(arrayList);
    }

Java进阶九—数组问题(集合框架)_第16张图片

 public void arrayListTest() {

        // 泛型为整数与浮点数时要使用他们的包装类
        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);

        System.out.println(arrayList);

        ArrayList arrayList1 = (ArrayList) arrayList.clone();

        // 拷贝
        System.out.println(arrayList1);

    }

Java进阶九—数组问题(集合框架)_第17张图片

5. 查看集合中是否有这个元素

 public void arrayListTest() {

        // 泛型为整数与浮点数时要使用他们的包装类
        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);

       // 返回boolean类型
        boolean number1 = arrayList.contains(3);
        System.out.println(number1);
        boolean number2 = arrayList.contains(5);
        System.out.println(number2);

    }

 Java进阶九—数组问题(集合框架)_第18张图片

6. 获取集合的容量与需要的下标值,与任何遍历

集合之所以可以直接输出不用遍历,是因为它重新了toString方法。

public void arrayListTest() {

        // 泛型为整数与浮点数时要使用他们的包装类
        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);

        // 集合容量
        System.out.println(arrayList.size());

        // 下标为2的值
        int indexTwo = arrayList.get(2);
        System.out.println(indexTwo);


        // 遍历,并给每一个元素加2,
        // 遍历的作用:不仅要输出,还有操作

        // 方法一:for循环数组遍历时使用length,而集合遍历使用size
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.print(arrayList.get(i)+2+"\t");
        }

        System.out.println();
        
        // 方法二:增强for循环
        for (Integer value : arrayList) {
            System.out.print(value+2+"\t");
        }

Java进阶九—数组问题(集合框架)_第19张图片

7. 给值找下标

  public void arrayListTest() {
        
        ArrayList arrayList = new ArrayList<>();

        arrayList.add("Man");
        arrayList.add("Tom");
        arrayList.add("Fuck");
        arrayList.add("LiLi");
        arrayList.add("Fuck");
        arrayList.add("JiJi");

        // 从前往后,查找最近的
        System.out.println(arrayList.indexOf("Fuck"));
        // 从后往前,查找最近的
        System.out.println(arrayList.lastIndexOf("Fuck"));
    }

Java进阶九—数组问题(集合框架)_第20张图片

8. 查看集合是否为空

public void arrayListTest() {

        ArrayList arrayList = new ArrayList<>();

        arrayList.add("Man");
        arrayList.add("Tom");
        arrayList.add("Fuck");

        // 集合是否为空
        System.out.println(arrayList.isEmpty());


        ArrayList arrayList1 = new ArrayList<>();

        // 集合是否为空
        System.out.println(arrayList1.isEmpty());
    }

Java进阶九—数组问题(集合框架)_第21张图片

9. 删除

 public void arrayListTest() {

        ArrayList arrayList = new ArrayList<>();

        arrayList.add("Man");
        arrayList.add("Tom");
        arrayList.add("Fuck");
        arrayList.add(null);

        System.out.println(arrayList);

        // 指定值删除,删除值为空的
        System.out.println(arrayList.remove(null));

        System.out.println(arrayList);
    }

Java进阶九—数组问题(集合框架)_第22张图片

public void arrayListTest() {

        ArrayList arrayList = new ArrayList<>();

        arrayList.add("Man");
        arrayList.add("Tom");
        arrayList.add("Fuck");
        arrayList.add(null);

        System.out.println(arrayList);

        // 指定下标删除,删除值为空的
        System.out.println(arrayList.remove(3));

        System.out.println(arrayList);
    }

Java进阶九—数组问题(集合框架)_第23张图片

 

 public void arrayListTest() {

        ArrayList arrayList = new ArrayList<>();

        arrayList.add("Man");
        arrayList.add("Tom");
        arrayList.add("Fuck");
        arrayList.add(null);

        System.out.println(arrayList);

        ArrayList arrayList1 = new ArrayList<>();

        arrayList1.add("Fuck");
        arrayList1.add(null);

        // 根据arrayList1集合元素删除arrayList里的相同元素
        arrayList.removeAll(arrayList1);

        System.out.println(arrayList);

    }

Java进阶九—数组问题(集合框架)_第24张图片

 10.两个集合取交集(相同元素)

 public void arrayListTest() {

        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);

        System.out.println(arrayList);

        ArrayList arrayList1 = new ArrayList<>();

        arrayList1.add(3);
        arrayList1.add(5);

        System.out.println(arrayList1);

        // 取交集
        System.out.println(arrayList.retainAll(arrayList1));

        // 原理是取完交集后,放在arrayList中
        System.out.println(arrayList);

    }

Java进阶九—数组问题(集合框架)_第25张图片

11. 替换

 public void arrayListTest() {

        ArrayList arrayList = new ArrayList<>();

        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);

        System.out.println(arrayList);

        // 把3替换成4
        arrayList.set(2,4);

        System.out.println(arrayList);

    }

Java进阶九—数组问题(集合框架)_第26张图片

12.排序与倒序 

 由于此方法要使用拉姆达表达式,使用我们采用另一种方法。 

集合 (Java Platform SE 8 ) (oracle.com)

public void arrayListTest() {

        ArrayList arrayList = new ArrayList<>();

        arrayList.add(7);
        arrayList.add(4);
        arrayList.add(0);
        arrayList.add(44);

        System.out.println(arrayList);

        // 排序,从小到大
        Collections.sort(arrayList);

        System.out.println(arrayList);

        // 倒序
        Collections.reverse(arrayList);

        System.out.println(arrayList);
        
    }

Java进阶九—数组问题(集合框架)_第27张图片

 13.取指定下标范围的值

public void arrayListTest() {

        ArrayList arrayList = new ArrayList<>();

        arrayList.add(7);
        arrayList.add(4);
        arrayList.add(0);
        arrayList.add(44);

        System.out.println(arrayList);

        // 查找下标1到3的值;
        System.out.println(arrayList.subList(1,4));

        // 之所以下标是1-4是因为,这个查找原理是这样的:1 <= 下标范围 < 4

    }

Java进阶九—数组问题(集合框架)_第28张图片

五.Linked链表

  • ArrayList数组集合,增删慢,查询快
  • LinkedList链表集合,增删快,查询慢

 数组集合之所以增删慢,是因为增删时集合内元素要移动Java进阶九—数组问题(集合框架)_第29张图片

 链表集合增删快,是因为链表集合增删时内部元素不需要移动Java进阶九—数组问题(集合框架)_第30张图片

六.LinkedList一带而过 

  • 链表是数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址
  • 链表可分为单向链表和双向链表
  • 由于黑老大定下的规矩,所以它跟ArrayList方法差不多相同。

LinkedList (Java Platform SE 8 ) (oracle.com)

 七.iterator 迭代器初试

  • 迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需目标或结果
  • 每一次对过程的重复被称为一次“迭代”,而每一次迭代的结果会被用来作为下一次迭代的初始值

 迭代器Iterator用于Conllections家族 ,不管用于ArrayList还是LinkedList都可以迭代输出

 public void arrayListTest() {

        // 数组集合
        ArrayList arrayList = new ArrayList<>();

        arrayList.add("Tom");
        arrayList.add("Fuck");
        arrayList.add("Lise");

        // 使用方式
        Iterator iterator = arrayList.iterator();
        // hasNext()判断是否有值
        while (iterator.hasNext()) {
            String value = iterator.next();
            System.out.println(value);
        }
    }

Java进阶九—数组问题(集合框架)_第31张图片

public void arrayListTest() {

        // 链表集合
        LinkedList linkedList = new LinkedList<>();

        linkedList.add("Tom");
        linkedList.add("Fuck");
        linkedList.add("Lise");

        // 使用方式
        Iterator iterator = linkedList.iterator();
        // hasNext()判断是否有值
        while (iterator.hasNext()) {
            String value = iterator.next();
            System.out.println(value);
        }
    }

Java进阶九—数组问题(集合框架)_第32张图片

八.fori、增强for、迭代器的区别、谈谈三者性能

  • for循环适合数据的读取与修改
  • 增强for循环适合数据的读取
  • Iterator不要使用for循环嵌套使用,适合数据的读取与修改
      public void arrayListTest() {
    
            // 链表集合
            LinkedList linkedList = new LinkedList<>();
    
            linkedList.add("Tom");
            linkedList.add("Fuck");
            linkedList.add("Lise");
    
            // 使用方式
            Iterator iterator = linkedList.iterator();
            // hasNext()判断是否有值
            while (iterator.hasNext()) {
                String value = iterator.next();
                // 删除Tom
                if (value.equals("Tom")) {
                    // 要使用iterator自带的remove()方法
                    iterator.remove();
                }
            }
            System.out.println(linkedList);
        }
    Java进阶九—数组问题(集合框架)_第33张图片

增强for循环是一个小型的迭代器了,如果一定要在增强for循环中修改集合的话可以使用迭代器,但不建议在增强for循环中直接修改Java进阶九—数组问题(集合框架)_第34张图片

 谈谈三者性能:比较时间复杂度

如果是 ArrayList ,用三种方式遍历的速度是for循环>Iterator>增强for循环,速度级别基本一致,一般都会用for循环或者增强for循环,因为Iterator写法相对复杂一些


如果是 LinkedList,则三种方式遍历的差距很大了,数据量大时越明显,Iterator>增强for循环>>>for循环,推荐使用增强for循环或者Iterator

List遍历:for,foreach Iterator 速度比较_list迭代器遍历执行慢-CSDN博客

九.Set和HashSet 

 HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合,允许有 null 值,是无序的,即不会记录插入的顺序。

 public void setTest() {

        // 使用Hash函数实现HashSet,元素无序,且不重复
        HashSet hashSet = new HashSet<>();

        hashSet.add("Tom");
        hashSet.add("Fuck");
        hashSet.add("LiLi");
        hashSet.add("LiLi");
        hashSet.add("Fuck");

        System.out.println(hashSet);
        
        // 之所以输出后没有顺序且是唯一,是由于hashSet的每一个元素都会给应该hash值
        // hash值相当与身份证,不重复是唯一的
    }

Java进阶九—数组问题(集合框架)_第35张图片

关于Java的Hash算法的深入理解-CSDN博客

十.LinkedHashSet 

如果要创建有序集合呢?LinkedHashSet便是有序的不重复的

 public void setTest() {

        LinkedHashSet linkedHashSet = new LinkedHashSet<>();

        linkedHashSet.add("Tom");
        linkedHashSet.add("Fuck");
        linkedHashSet.add("LiLi");
        linkedHashSet.add("LiLi");
        linkedHashSet.add("Fuck");

        System.out.println(linkedHashSet);

    }

Java进阶九—数组问题(集合框架)_第36张图片

十一.Map、HashMap、Entry 

 HashMap (Java Platform SE 8 ) (oracle.com)

 public void mapTest() {

        // 有两个泛型:第一个为key(钥匙),第二个为value(值)
        HashMap hashMap = new HashMap<>();

        hashMap.put(10000000,"Fuck");
        hashMap.put(10000001,"Tom");
        hashMap.put(10000002,"LiLi");
        hashMap.put(10000003,"Man");

        System.out.println(hashMap);

        // 1.输出编号为10000000的人
        String value = hashMap.get(10000000);
        System.out.println(value);

        // 2.删除编号10000001的人
        hashMap.remove(10000001);
        System.out.println(hashMap);

        // 3.是否包含编号为10000002的人与叫Fuck的人
        System.out.println(hashMap.containsKey(10000002));
        System.out.println(hashMap.containsValue("Fuck"));

        // 4.替换编号为10000003的人的名字为Dog
        hashMap.replace(10000003,"Dog");
        System.out.println(hashMap);

        // 5.保存编号
        Set keys = hashMap.keySet();
        System.out.println(keys);

        // 6.保存编号与名字
        Set> entrySet = hashMap.entrySet();
        System.out.println(entrySet);

    }

Java进阶九—数组问题(集合框架)_第37张图片

已经存在的键值对,再次.put()会替换原来的,.get()不存在的值会返回null Java进阶九—数组问题(集合框架)_第38张图片

十二. Entry与Map转换Set之后遍历: Iterator> iterator = entrySet.iterator(); 

  • 之所以使用Entry把Map转换Set是因为之后方便遍历
  • Entry就是用来管理键值对对象的,将对象包裹起来,提供遍历的方式
  • Entry可以使用迭代器,筛选值,但只适合在内存中使用,不适用于JDBC
  public void MapTest() {

        HashMap hashMap = new HashMap<>();

        System.out.println("学生准考证号与成绩");

        hashMap.put(10000000,88);
        hashMap.put(10000001,49);
        hashMap.put(10000002,53);
        hashMap.put(10000003,83);
        hashMap.put(10000004,71);

        System.out.println(hashMap);

        System.out.println("80分以上的分数");
        // 使用Set保存学生准考证号与成绩方便遍历
        Set> entrySet = hashMap.entrySet();
        // 使用ArrayList保存80分以上的分数
        ArrayList arrayList = new ArrayList<>();

        // 迭代器的泛型是Map.Entry不要出错
        Iterator> iterator = entrySet.iterator();

        while (iterator.hasNext()) {
            // 取出学生成绩放入vaLue
            int value = iterator.next().getValue();
            // 判断80分以上的分数
            if (value > 80) {
               arrayList.add(value);
            }
        }
        System.out.println(arrayList);
    }

Java进阶九—数组问题(集合框架)_第39张图片

 

 十三.LinkedHashMap

HashMap是无序的,可以自定义泛型,而LinkedHashMap相当于有序的HashMap 

LinkedHashMap (Java Platform SE 8 ) (oracle.com) 

 

十四.集合框架部分结束 

剩下的类需要自己去学习了!了解各类是怎么实现的,以及其之间的区别,JDK的新特性暂时用不到,还没学习到框架 

你可能感兴趣的:(java,开发语言)