【Java基础|第二十五篇】集合与集合框架(五)——Map实现类与Collections工具类

(五)集合与集合框架

11、Map实现类:

(1)HasgMap:

         HashMap底层借助哈希表实现,元素的存取顺序不能保证一致。

        HashMap存储的键值对时,如果键类型为自定义类,那么一般需要重写键所属类的hashCode()和equals()方法(重要,最常用)。

HashMap特点:

  • 键唯一
  • 值可重复
  • 无序性
  • 线程不安全
  • 键和值的允许使用null【重点记忆】 
public class Test083_HashMap {
    public static void main(String[] args) {
        //1.实例化HashMap对象,其中key类型为自定义Student
        Map<Student, String> map = new HashMap<>();
        //2.往集合中添加元素
        // map中插入键值对,调用key所属类的hashCode和equals方法进行判断是否重复
        map.put(new Student("zs", 78), "010");
        map.put(new Student("rose", 82), "005");
        map.put(new Student("lucy", 70), "009");
        map.put(new Student("lucy", 70), "019"); //相同key,只能保留一项,"019"会覆盖"009"
        map.put(new Student("ww", 67), "002");
        //注意:HashMap中key和value都可以为null
        map.put(new Student("tom", 86), null);
        map.put(null, "002");
        //3.基本方法测试
        // 获取长度
        System.out.println("size: " + map.size());
        // 判断key是否存在
        // 借助 key所属类的hashCode和equals方法完成
        System.out.println("Student(ww,67)是否存在: " +
        map.containsKey(new Student("ww", 67)));
        // 判断value是否存在
        // 借助value所属类型的 equals方法
        System.out.println("是否存在 009: " +
        map.containsValue("009"));
        // 根据key删除,返回键对应的值
        String value = map.remove(new Student("lucy", 70));
        System.out.println("remove(Student(lucy, 70)): " + value);
        System.out.println("---------------");
        // 4.第一种遍历方法
        Set<Student> keySet = map.keySet();
        for (Student key : keySet) {
            System.out.println(key + ": " + map.get(key));
        }
        System.out.println("---------------");
        // 第二种方式遍历
        Set<Entry<Student, String>> entrySet = map.entrySet();
        for (Entry<Student, String> entry : entrySet) {
            System.out.println(entry.getKey() + ": " +
            entry.getValue());
        }
    }
}

//运行结果:
size: 6
Student(ww,67)是否存在: true
是否存在 009: false
remove(Student(lucy, 70)): 019
---------------
null: 002
Student [name=rose, age=82]: 005
Student [name=zs, age=78]: 010
Student [name=tom, age=86]: null
Student [name=ww, age=67]: 002
---------------
省略...

要注意,我在放代码时并没有导包,大家要注意,我主要是展示方法的用法与功能
(2)Hashtable:

Hashtable的特点:

  • 键唯一
  • 值可重复
  • 无序性
  • 线程安全,但性能不如HashMap,单线程用HashMap,多线程用Hashtable。
  • 键和值都允许使用null
  • 底层是哈希表

案例展示:

public class Test084_Hashtable {
    public static void main(String[] args) {
        // 1.实例化HashMap对象,其中key类型为自定义Student
        Hashtable<Student, String> map = new Hashtable<>();
        // 2.往集合中添加元素
        // map中插入键值对,调用key所属类的hashCode和equals方法进行判断是否重复
        map.put(new Student("zs", 78), "010");
        map.put(new Student("rose", 82), "005");
        map.put(new Student("lucy", 70), "009");
        map.put(new Student("lucy", 70), "019"); // 相同key,只能保留一项,"019"会覆盖"009"
        map.put(new Student("ww", 67), "002");
        // 注意:Hashtable中key和value不能为null,否则抛出NullPointerException
        //map.put(new Student("tom", 86), null);
        //map.put(null, "002");
        // 3.遍历,Hashtable早期提供的方法较为繁琐
        Enumeration<Student> keys = map.keys();
        while(keys.hasMoreElements()) {
            Student key = keys.nextElement();
            String value = map.get(key);
            System.out.println(key + ": " + value);
        }
    }
}

//运行输出:
Student [name=lucy, age=70]: 019
Student [name=zs, age=78]: 010
Student [name=ww, age=67]: 002

(3)TreeMap

        TreeMap是Map接口的子类SortedMap的实现类

TreeMap的特点:

  • 键唯一
  • 值可重复
  • 顺序可以按照自然排序或者比较器排序,比较器优先于自然排序
  • 线程不安全
  • key不能取null,value可以取null
  • 底层是红黑树

注意:相比于HashMap等实现类,TreeMap在插入和删除操作上可能稍慢。因此,在选择使用TreeMap时,需要根据具体需求权衡性能和有序性的需求。

案例展示:一个比较器排序的例子

//注意导入自定义Student类
import com.briup.chap08.bean.Student;
//比较器排序
public static void main(String[] args) {
    //1.额外提供比较器对象
    Comparator<Student> comp = new Comparator<Student>() {
        @Override
        public int compare(Student o1, Student o2) {
            //先按照名字降序
            int r = o2.getName().compareTo(o1.getName());
            //如果年龄一样,再按照年龄升序
            if(r == 0)
                r = o1.getAge() - o2.getAge();
                return r;
            }
        };
    //2.实例化TreeMap对象
    Map<Student, String> map = new TreeMap<>(comp);
    //3.添加键值对
    map.put(new Student("zs", 78),"010");
    map.put(new Student("rose", 82),"005");
    map.put(new Student("lucy", 79),"009");
    map.put(new Student("lucy", 79),"009");
    map.put(new Student("tom", 68),"019");
    map.put(new Student("tom", 86),"012");
    map.put(new Student("ww", 67),"002");
    //key不能为null,否则出 NullPointerException
    //map.put(null,"002");
    //4.遍历
    Set<Entry<Student,String>> entrySet = map.entrySet();
    for (Entry<Student, String> entry : entrySet) {
        System.out.println(entry.getKey() + ": " +
        entry.getValue());
    }
}

//运行结果:
Student [name=zs, age=78]: 010
Student [name=ww, age=67]: 002
Student [name=tom, age=68]: 019
Student [name=tom, age=86]: 012
Student [name=rose, age=82]: 005
Student [name=lucy, age=79]: 009

(4)LinkedHashmap

LinkedHashMap的特点:

  • 键唯一
  • 值可重复
  • 有序性,与插入顺序一致
  • 线程不安全
  • 键和值的允许使用null
  • 底层是哈希表+链表

12、Collections工具类:

(1)概述:

        属于util包,使用需要导包

        类似于Array类,Collections类专门来操作集合对象,里面都是静态方法,可以直接调用。

        Collections类无继承,无实现,父类为Object,私有构造器,只能通过类名调用方法与属性。

        与Collection接口毫无关系

(2)方法:

1. fill(List<? super T> list, T obj)

  • 用法:将列表中所有元素替换为指定对象obj

  • 参数:

    • list:要填充的列表(必须是可修改的,否则抛UnsupportedOperationException)。

    • obj:用于替换列表元素的对象(可以为null)。

  • 返回值:void(无返回值)。

  • 被调用者:Collections工具类(静态方法,直接通过类名调用)。

  • 示例:

    List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
    Collections.fill(list, "x"); // 列表变为 ["x", "x", "x"]
    

2. max(Collection<? extends T> coll) 与 max(Collection<? extends T> coll, Comparator<? super T> comp)

  • 用法:返回集合中的最大元素。

  • 参数:

    • coll:要查找最大元素的集合(非空,否则抛NoSuchElementException)。

    • 重载方法max(Collection, Comparator):通过自定义比较器comp定义排序规则。

  • 返回值:集合中的最大元素(类型为T)。

  • 要求:

    • 无比较器的版本:集合元素必须实现Comparable接口(否则抛ClassCastException)。

    • 有比较器的版本:通过比较器定义元素的大小关系。

  • 示例:

    List<Integer> nums = Arrays.asList(3, 1, 4);
    Integer max = Collections.max(nums); // 返回4(依赖Integer的自然排序)
    
    // 自定义比较器(字符串按长度排序)
    List<String> strs = Arrays.asList("apple", "cat", "banana");
    String longest = Collections.max(strs, Comparator.comparingInt(String::length));
    // longest = "banana"(长度最长)
    

3. min(Collection<? extends T> coll) 与 min(Collection<? extends T> coll, Comparator<? super T> comp)

  • 用法:返回集合中的最小元素(与max逻辑对称)。

  • 参数:同max方法。

  • 返回值:集合中的最小元素(类型为T)。

  • 示例:

    List<Integer> nums = Arrays.asList(3, 1, 4);
    Integer min = Collections.min(nums); // 返回1
    
    List<String> strs = Arrays.asList("apple", "cat", "banana");
    String shortest = Collections.min(strs, Comparator.comparingInt(String::length));
    // shortest = "cat"(长度最短)
    

4. reverse(List<?> list)

  • 用法:反转列表中元素的顺序(第一个元素与最后一个交换,第二个与倒数第二个交换,以此类推)。

  • 参数:list为要反转的列表(必须可修改)。

  • 返回值:void

  • 示例:

    List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
    Collections.reverse(list); // 列表变为 [4, 3, 2, 1]
    

5. sort(List<T> list) 与 sort(List<T> list, Comparator<? super T> c)

  • 用法:对列表进行排序(原地排序,修改原列表)。

  • 参数:

    • list:要排序的列表(必须可修改且支持随机访问,如 ArrayList;LinkedList 排序效率低)。

    • 重载方法sort(List, Comparator):通过比较器c定义排序规则。

  • 返回值:void

  • 排序规则:

    • 无比较器版本:元素需实现Comparable接口,按自然顺序排序。

    • 有比较器版本:按比较器定义的规则排序。

  • 示例:

    List<Integer> nums = new ArrayList<>(Arrays.asList(3, 1, 4));
    Collections.sort(nums); // 自然排序,结果 [1, 3, 4]
    
    List<String> strs = new ArrayList<>(Arrays.asList("banana", "apple", "cat"));
    // 按字符串长度排序
    Collections.sort(strs, Comparator.comparingInt(String::length));
    // 结果 ["cat", "apple", "banana"]
    

6. shuffle(List<?> list) 与 shuffle(List<?> list, Random rnd)

  • 用法:随机打乱列表中元素的顺序(基于随机数)。

  • 参数:

    • list:要打乱的列表(必须可修改)。

    • 重载方法shuffle(List, Random):使用指定的随机数生成器rnd,可控制随机性(如固定种子实现可重复的打乱结果)。

  • 返回值:void

  • 示例:

    List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
    Collections.shuffle(list); // 随机打乱,结果可能为 [3, 1, 4, 2](每次不同)
    
    // 固定种子,打乱结果可重复
    Random random = new Random(100); // 固定种子100
    Collections.shuffle(list, random);
    

7. addAll(Collection<? super T> c, T... elements)

  • 用法:将多个元素批量添加到集合中(相当于多次调用add方法,但更高效)。

  • 参数:

    • c:目标集合(必须支持add操作,否则抛UnsupportedOperationException)。

    • elements:可变参数,要添加的元素(可为 0 个或多个)。

  • 返回值:boolean类型,true表示集合因添加而发生改变(至少添加了一个元素)。

  • 示例:

    List<String> list = new ArrayList<>();
    // 添加多个元素
    boolean changed = Collections.addAll(list, "a", "b", "c");
    // list变为 ["a", "b", "c"],changed = true
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Test09_Collections {
    public static void main(String[] args) {
        //1.准备集合并添加元素
        //List<Integer> list = Arrays.asList(5,3,4,2,2,7);
        List<Integer> list = new ArrayList<>();
        //addAll 往集合中添加多个元素
        Collections.addAll(list,5,3,4,2,2,7);
        System.out.println(list);
        //2.max 获取最大值【默认采用自然排序】
        Integer max = Collections.max(list);
        System.out.println("max: " + max);
        //3.min 获取集合最小值
        Integer min = Collections.min(list);
        System.out.println("min: " + min);
        //4.reverse 反转
        Collections.reverse(list);
        System.out.println(list);
        //4.sort 排序【按照 传入的排序算法 进行排序】
        Comparator<Integer> comp = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 逆序
                return o2-o1;
            }
        };
        //注意:排序不会删除集合中的元素
        Collections.sort(list,comp);
        System.out.println("逆序: " + list);
        //5.shuffle 随机打乱
        Collections.shuffle(list);
        System.out.println("打乱: " + list);
        //6.sort 排序【默认自然排序】
        Collections.sort(list);
        System.out.println("自然排序: " + list);
        //7.fill 填充
        Collections.fill(list, 20);
        System.out.println("after fill: " + list);
        //8.将ArrayList【线程不安全】的集合 转换成 线程安全集合
        //List<Integer> list2 = Collections.synchronizedList(list);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值