IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 5-Collections、Set、Map和集合的嵌套 -> 正文阅读

[PHP知识库]5-Collections、Set、Map和集合的嵌套


前言

提示:这里介绍的是Collections、Set、Map和集合的嵌套的基础知识点


提示:以下是本篇文章正文内容,下面案例可供参考

一、Collections类

1、概述:

java.util.Collections是集合工具类,用来对集合进行操作。

2、常用方法:

public static void shuffle(List<?> list) :打乱集合顺序。

public class Test1_shuffle {
    public static void main(String[] args) {
        // public static void shuffle(List<?> list) :打乱集合顺序。
        // 创建List集合对象,限制集合元素类型为Integer
        List<Integer> list = new ArrayList<>();

        // 往集合中添加元素
        list.add(500);
        list.add(200);
        list.add(400);
        list.add(100);
        list.add(300);

        // 打印集合
        System.out.println("打乱顺序之前的集合:"+list);

        // 打乱集合元素顺序
        Collections.shuffle(list);

        // 打印集合
        System.out.println("打乱顺序之后的集合:"+list);
    }
}

public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。

  • 默认规则: 事先写好的规则
  • 默认规则是在哪里指定的?
    • 在集合元素所属的类中指定的
  • 默认规则如何指定?
    • 要求集合元素所属的类必须实现Comparable接口,重写compareTo方法,在compareTo方法中书写默认排序规则
public class Test2_sort默认规则排序 {
    public static void main(String[] args) {
        // public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
        // 创建List集合对象,限制集合元素类型为Integer
        List<Integer> list = new ArrayList<>();

        // 往集合中添加元素
        list.add(500);
        list.add(200);
        list.add(400);
        list.add(100);
        list.add(300);

        // 打印集合
        System.out.println("排序之前的集合:"+list);

        // 使用默认规则进行排序
        Collections.sort(list);

        // 打印集合
        System.out.println("排序之后的集合:"+list);
    }
}

//Student
public class Student implements Comparable<Student>{
    String name;
    int age;

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

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

    @Override
    public int compareTo(Student o) {
        // 指定默认规则排序
        // 升序: 前减后
        // 降序: 后减前
        // 前: this  后: 参数o
        //return this.age - o.age;
        return o.age - this.age;
    }
}

//测试
public static void main(String[] args) {
        // public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
        // 创建List集合对象,限制集合元素类型为Student
        List<Student> list = new ArrayList<>();

        // 往集合中添加元素
        list.add(new Student("张三1",18));
        list.add(new Student("张三2",38));
        list.add(new Student("张三3",28));
        list.add(new Student("张三4",48));
        list.add(new Student("张三5",58));

        // 打印集合
        System.out.println("排序之前的集合:"+list);

        // 使用默认规则进行排序
        Collections.sort(list);

        // 打印集合
        System.out.println("排序之后的集合:"+list);
    }
}

public <T> void sort(List<T> list,Comparator<? super T> comp):将集合中元素按照指定规则排序

案例1public class Test4_sort指定规则排序 {
    public static void main(String[] args) {
        // public <T> void sort(List<T> list,Comparator<? super T> comp):将集合中元素按照指定规则排序
        // 创建List集合对象,限制集合元素类型为Integer
        List<Integer> list = new ArrayList<>();

        // 往集合中添加元素
        list.add(500);
        list.add(200);
        list.add(400);
        list.add(100);
        list.add(300);

        // 打印集合
        System.out.println("排序之前的集合:"+list);

        // 使用指定规则进行排序
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 指定排序规则
                // 升序: 前减后
                // 降序: 后减前
                // 前: 第一个参数o1, 后:第二个参数o2
                return o1 - o2;
            }
        });

        // 打印集合
        System.out.println("排序之后的集合:"+list);// [100, 200, 300, 400, 500]

        // 使用指定规则进行排序
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 指定排序规则
                // 升序: 前减后
                // 降序: 后减前
                // 前: 第一个参数o1, 后:第二个参数o2
                return o2 - o1;
            }
        });

        // 打印集合
        System.out.println("排序之后的集合:"+list);// [500, 400, 300, 200, 100]
    }
}


//案例2
public class Test5_sort指定规则排序 {
    public static void main(String[] args) {
        // public <T> void sort(List<T> list,Comparator<? super T> comp):将集合中元素按照指定规则排序
        // 创建List集合对象,限制集合元素类型为Student
        List<Student> list = new ArrayList<>();

        // 往集合中添加元素
        list.add(new Student("张三1",18));
        list.add(new Student("张三2",38));
        list.add(new Student("张三3",28));
        list.add(new Student("张三4",48));
        list.add(new Student("张三5",58));

        // 打印集合
        System.out.println("排序之前的集合:"+list);

        // 使用指定规则进行排序--->按照年龄升序
       Collections.sort(list, new Comparator<Student>() {
           @Override
           public int compare(Student o1, Student o2) {
               // 升序: 前减后
               return o1.age - o2.age;
           }
       });

        // 打印集合
        System.out.println("排序之后的集合:"+list);

        // 使用指定规则进行排序--->按照年龄降序
        Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 降序: 后减前
                return o2.age - o1.age;
            }
        });


        // 打印集合
        System.out.println("排序之后的集合:"+list);
    }
}


3、可变参数

3.1、概述:

在JDK1.5之后,定义了可变参数,用来表示一个方法需要接受的多个同类型参数。

3.2、格式:

修饰符 返回值类型 方法名(数据类型... 变量名){
    
}
案例:
public class Test {
    public static void main(String[] args) {
        // 调用method1方法
        method1();
        System.out.println("--------");

        method1(10);
        System.out.println("--------");

        method1(10,20);
        System.out.println("--------");

        method1(10,20,30);
        System.out.println("--------");

        method1(10,20,30,40);
        System.out.println("--------");

        int[] arr = {10,20,30,40,50};
        method1(arr);
        // ...
    }

    // 定义一个方法可以接收多个int类型的参数
    public static void method1(int... nums){
        // 使用: 把可变参数当成数组来使用
        for (int i = 0; i < nums.length; i++) {
            System.out.println(nums[i]);
        }
    }
}

3.3、注意事项:

注意事项:

- 可变参数一定是定义在方法的形参位置
- 一个方法只能有一个可变参数
- 如果方法中有多个参数,可变参数要放到最后。
public class Test_注意事项 {
    public static void main(String[] args) {
      method2("itheima",10,20,30);
    }
    
    // - 一个方法只能有一个可变参数
   /* public static void method1(int... nums,String... strs){// 编译报错
        
    }*/
   
    // - 如果方法中有多个参数,可变参数要放到最后。
    /*public static void method2(int... nums,String str){// 编译报错
        
    }*/

    public static void method2(String str,int... nums){

    }
}

3.4、应用场景

Collections工具类中的批量添加元素的静态方法:
static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。

public static void main(String[] args) {
        // 可变参数应用场景:
        // static <T> boolean addAll(Collection<T> c, T... elements)  :往集合中添加一些元素。
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");
        System.out.println("list:" + list);
    }

二、Set接口

1、 Set接口介绍

概述:

java.util.Set接口继承自Collection接口,是单列集合的一个重要分支。

特点:

元素没有索引,元素唯一(不重复)

注意事项:

  - Set集合元素没有索引,只能使用迭代器或者增强for循环进行遍历元素
  - Set集合没有特殊的方法,都是使用Collection的方法
  - Set接口就是Set集合,但凡实现了Set接口的类也叫做Set集合

常用实现类:

  - HashSet类:  元素没有索引,元素唯一,元素存取顺序不一致
    - 存储结构采用的是哈希表结构,由哈希表保证元素唯一
  - LinkedHashSet类:元素没有索引,元素唯一,元素存取顺序一致
    - 存储结构采用的是哈希表+链表结构,由哈希表保证元素唯一,由链表保证元素存取顺序一致
  - TreeSet类: 元素没有索引,元素唯一,可以对元素进行排序
    - 存储结构采用的是红黑树结构,由红黑树保证元素唯一,由比较器来对元素进行排序

2、 HashSet集合

- 概述:

java.util.HashSet是Set接口的一个实现类, 底层的实现其实是一个java.util.HashMap支持

特点:

元素没有索引,元素唯一,元素存取顺序不一致

案例:

public class Test {
    public static void main(String[] args) {
        // 创建HashSet集合,限制集合元素的类型String
        HashSet<String> set = new HashSet<>();

        // 添加元素
        set.add("nba");
        set.add("bac");
        set.add("cba");
        set.add("abc");
        set.add("nba");

        // 打印集合
        System.out.println("set:"+set);
    }
}

HashSet集合存储数据的结构(哈希表)

在**JDK1.8**之前,哈希表底层采用数组+链表实现,即使用数组处理冲突,同一hash值的链表都存储在一个数组里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,如下图所示。
原理图
HashSet保证元素唯一原理

保证元素唯一的原理: 依靠hashCode和equals方法
1.存储元素的时候,会调用该元素的hashCode方法计算该元素的哈希值
2.判断该哈希值对应的位置上是否有元素
3.如果该哈希值对应的位置上没有元素,就直接存储
4.如果该哈希值对应的位置上有元素,说明产生了哈希冲突
5.产生了哈希冲突就会调用该元素的equals方法与该哈希值对应的位置上的所有元素进行一一比较:
5.1 如果比较完之后,没有一个元素与该元素相等,就直接存储
5.2 如果比较完之后,有任意一个元素与该元素相等,就不存储

注意:
1.hashCode和equals方法属于Object类的
2.任意类的对象都拥有hashCode和equals方法
3.Object类中的hashCode方法是主要根据地址值计算哈希值
4.Object类中的equals方法是比较地址值

HashSet存储自定义类型元素

需求: 使用HashSet集合存储学生对象

结论: HashSet存储自定义类型元素,要求该元素所属的类要重写hashCode和equals方法

3、 LinkedHashSet

概述:

java.util.LinkedHashSet 是HashSet的一个子类,底层采用链表+哈希表

特点:

元素没有索引,元素唯一,元素存取顺序一致
存储结构采用的是哈希表+链表结构,由哈希表保证元素唯一,由链表保证元素存取顺序一致
如果集合中存储的是自定义类型的元素,那么就要求该元素所属的类要重写hashCode和
equals方法

案例:

public class Test {
    public static void main(String[] args) {
        // 创建LinkedHashSet集合,限制集合元素的类型为String
        LinkedHashSet<String> set = new LinkedHashSet<>();

        // 往集合中添加元素
        set.add("nba");
        set.add("cba");
        set.add("bac");
        set.add("abc");
        set.add("nba");

        // 打印集合
        System.out.println("set:" + set);

        System.out.println("========");

        // 1.创建LinkedHashSet集合对象,限制集合元素类型为Student
        LinkedHashSet<Student> set2 = new LinkedHashSet<>();

        // 2.创建学生对象
        Student stu1 = new Student("张三",18);
        Student stu2 = new Student("李四",28);
        Student stu3 = new Student("王五",38);
        Student stu4 = new Student("赵六",48);
        Student stu5 = new Student("张三",18);

        // 3.把学生对象添加到集合中
        set2.add(stu1);
        set2.add(stu2);
        set2.add(stu3);
        set2.add(stu4);
        set2.add(stu5);

        // 4.循环遍历集合
        for (Student stu : set2) {
            System.out.println(stu);
        }
    }
}

4、TreeSet集合

概述:

TreeSet集合是Set接口的一个实现类,底层依赖于TreeMap,是一种基于红黑树的实现

特点:

  - 元素没有索引,元素唯一,可以对元素进行排序
  - 存储结构采用的是红黑树结构,由红黑树保证元素唯一,由比较器来对元素进行排序

排序:

  - 默认规则排序:  `public TreeSet(); 创建TreeSet集合对象,该集合对象使用默认规则对元素进行排序`
    - 默认规则是在元素所属的类中指定的
    - **要求集合元素所属的类必须实现Comparable接口,重写compareTo方法,在compareTo方法中指定排序规则**

三、Map集合

1、Map概述

- 概述: java.util.Map双列集合的顶层接口,用来存储具备映射关系对象的集合接口定义

特点:

  - Map<K,V>,K用来限制键的类型,V用来限制值的类型
  - Map集合以键值对的形式来存储数据
  - Map集合的键是唯一的,值可以重复,但键如果重复,值就会覆盖
  - Map集合是根据键来找值

实现类:

实现类都有的特点: 键是唯一的,值可以重复,但键如果重复,值就会覆盖
HashMap: 键值对存取顺序不一致
    	 底层哈希表结构,由哈希表保证键唯一
LinkedHashMap:键值对存取顺序一致
    	 底层哈希表+链表结构,由哈希表保证键唯一,由链表保证存取顺序一致
TreeMap: 可以对键进行排序,从而实现键值对排序
    	 底层红黑树结构,由红黑树保证键唯一,由比较器对象对元素进行排序

2、 Map的常用方法

  • public V put(K key, V value): 把指定的键与指定的值添加到Map集合中。
  • public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
  • public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
  • public boolean containsKey(Object key):判断该集合中是否有此键
  • public boolean containsValue(Object value):判断该集合中是否有此值
  • public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。
  • public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的 键值对对象 的集合(Set集合)。

3、 Map的遍历

方式1:键找值方式

- 获取Map集合的所有键--->keySet()方法
- 循环遍历所有的键
- 根据键找值--->get(K k)方法

案例:

public class Test1_键找值的方式 {
    public static void main(String[] args) {

        // 创建Map集合,限制键的类型String,值的类型String
        Map<String, String> map = new HashMap<>();

        // 添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");
        map.put("李亚鹏", "王菲");


        // - 获取Map集合的所有键
        Set<String> keys = map.keySet();

        // - 循环遍历所有的键
        for (String key : keys) {
            // - 根据键找值
            String value = map.get(key);
            System.out.println("key:"+key+",value:"+value);
        }
    }
}

方式2:键值对对象方式

- 获取所有的键值对对象---->entrySet()方法
- 循环遍历所有的键值对对象
- 使用键值对对象获取键和值--->使用Entry接口的方法
- Entry<K,V>接口:
  - Entry接口是Map接口的成员内部接口,使用的方式是Map.Entry<K,V>
  - Entry表示键值对对象,也就是说Entry是用来封装键值对的
  - Entry接口里面的常用方法:
    - K getKey(); 获取键值对对象封装的键
    - V getValue(); 获取键值对对象封装的值

- 案例:

public class Test2_键值对对象的方式 {
    public static void main(String[] args) {

        // 创建Map集合,限制键的类型String,值的类型String
        Map<String, String> map = new HashMap<>();

        // 添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");
        map.put("李亚鹏", "王菲");

        // - 获取所有的键值对对象---->entrySet()方法
        Set<Map.Entry<String, String>> set = map.entrySet();

        // - 循环遍历所有的键值对对象
        for (Map.Entry<String, String> entry : set) {
            // - 使用键值对对象获取键和值--->使用Entry接口的方法
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println("key:"+key+",value:"+value);
        }
    }
}

4、 HashMap存储自定义类型

结论: 如果键是自定义类型的元素,要保证键唯一,那么该键所属的类需要重写hashCode和equals方法

5、LinkedHashMap

概述:

LinkedHashMap是HashMap子类,底层由链表和哈希表组合,由哈希表保证键唯一,由链表保证键值对存取顺序一致
  • 结论: 如果键是自定义类型的元素,要保证键唯一,那么该键所属的类需要重写hashCode和equals方法

6、TreeMap集合

概述: TreeMap是Map实现类,底层由红黑树实现,可以对元素的键进行排序

构造方法:

  • public TreeMap();创建TreeMap集合对象,使用默认规则对键进行排序
public class Test1_默认规则排序 {
    public static void main(String[] args) {
        // 创建TreeMap集合,限制键的类型为Integer,值的类型为String
        TreeMap<Integer, String> map = new TreeMap<>();

        // 添加键值对
        map.put(500, "深圳");
        map.put(100, "北京");
        map.put(400, "广州");
        map.put(200, "上海");
        map.put(300, "杭州");

        // 遍历map集合,打印输出
        Set<Integer> keys = map.keySet();
        for (Integer key : keys) {
            String value = map.get(key);
            System.out.println(key + " = " + value);
        }
        
        // 结论: 如果键是自定义类型的元素,那么就要求键所属的类需要实现Comparable接口,重写compareTo方法,指定排序规则
    }
}

public TreeMap(Comparator<? super K> comparator);创建TreeMap集合对象,使用指定规则对键进行排序

public class Test2_指定规则排序 {
    public static void main(String[] args) {
        // 指定规则排序: 降序
        // 创建TreeMap集合,限制键的类型为Integer,值的类型为String
        TreeMap<Integer, String> map = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });

        // 添加键值对
        map.put(500, "深圳");
        map.put(100, "北京");
        map.put(400, "广州");
        map.put(200, "上海");
        map.put(300, "杭州");

        // 遍历map集合,打印输出
        Set<Integer> keys = map.keySet();
        for (Integer key : keys) {
            String value = map.get(key);
            System.out.println(key + " = " + value);
        }
        
    }
}

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:26:09  更:2021-09-22 14:27:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:07:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码