【JavaSE】集合专项练习篇(附源码)(下)

简介: 文章目录1 CollectionTest01.java2 CollectionTest02.java3 CollectionTest03.java4 简答题4.1 试分析 HashSet 与 TreeSet 分别如何实现去重的?5 代码分析题5.1 下面的代码是否会抛出异常,并从源码层面说明原因?5.2 Person类按照id和name重写了hashCode和equals方法,问下面代码输出什么?(容易踩坑)写在最后


3 CollectionTest03.java

按照要求完成下列任务

(1)使用HashMap类实例化一个Map类型的对象m,键(String)和值(int)分别用于存储员工的姓名和工资,存入数据如下:

jack-650元;tom-1200元;smith-2900元;

(2)将jack的工资更改为2600元;

(3)为所有员工工资加薪100元;

(4)遍历所有员工;

(5)遍历所有工资。


🦁 参考代码及运行结果:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 */
public class Collection03 {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("jack", 650);  // int - Integer
        map.put("tom", 1200);
        map.put("smith", 2900);
        System.out.println("初始数据: " + map);
        // 更新jack工资
        map.put("jack", 2600);
        System.out.println("jack工资更新: " + map);
        // 所有员工加薪100元
        Set keySet = map.keySet();
        for (Object key :
                keySet) {
            // 更新
            map.put(key, (Integer)map.get(key) + 100);
        }
        System.out.println("所有员工加薪100元: " + map);
        // 遍历员工与工资
        Set entrySet = map.entrySet();
        Iterator iterator = entrySet.iterator();
        while (iterator.hasNext()){
            Map.Entry entry = (Map.Entry)iterator.next();
            System.out.println(entry.getKey() + "-" + entry.getValue());
        }
    }
}



4 简答题

4.1 试分析 HashSet 与 TreeSet 分别如何实现去重的?

❓ 试分析 HashSet 与 TreeSet 分别如何实现去重的?


  1. HashSet的去重机制: hashCode() + equals(),底层先通过存入对象,进行运算得到一个 hash值,通过 hash值得到对应的索引,如果发现table索引所在位置,没有数据,则直接存放;如果有数据,则进行equals比较(由程序员决定),遍历该链表,如果遍历比较后都不相同,则加入,否则不加入。
  2. TreeSet的去重机制: 如果传入了一个 Comparator匿名对象,则使用实现的 compare去重,如果方法返回0,则认为是相同数据,则不添加。如果没有传入 Comparator匿名对象,则以添加的对象实现的 Compareable 接口的 compareTo 去重。

5 代码分析题

5.1 下面的代码是否会抛出异常,并从源码层面说明原因?

TreeSet treeSet = new TreeSet();
treeSet.add(new Person());

答: 会。因为 TreeSet() 构造器没有传入 Comparator接口的匿名内部类,所以在底层会把 Person 对象 转成 Comparable 类型,但是,Person并没有实现该接口,所以会报异常:ClassCastException。


5.2 Person类按照id和name重写了hashCode和equals方法,问下面代码输出什么?(容易踩坑)

import java.util.HashSet;
import java.util.Objects;
/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 */
public class MyTest {
    public static void main(String[] args) {
        HashSet set = new HashSet();
        Person p1 = new Person(1001, "AA");
        Person p2 = new Person(1002, "BB");
        set.add(p1);
        set.add(p2);
        p1.name = "CC";
        set.remove(p1);
        System.out.println(set);
        set.add(new Person(1001, "CC"));
        System.out.println(set);
        set.add(new Person(1001, "AA"));
        System.out.println(set);
    }
}
class Person{
    public int id;
    public String name;
    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
        return id == person.id && Objects.equals(name, person.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

🦁 注意陷阱!


在添加第一个 Person{1001, “AA”}时,hash值已经确定,而当修改AA为CC时,并不会更改hash值,而后,通过remove删除时,找不到原来的AA位置,所以导致删除失败!

在添加CC时,重新计算了hash值,和AA修改CC的索引并不相同,因此可以成功加入;

在最后添加AA时,计算出索引位置为第一个 Person的位置,但是其内容已经为CC,因此,能够以链表的形式接在其后面,也能添加成功!

相关文章
|
4月前
|
安全 Java
从零开始学习 Java:简单易懂的入门指南之不可变集合、方法引用(二十六)
从零开始学习 Java:简单易懂的入门指南之不可变集合、方法引用(二十六)
|
21天前
|
JavaScript Java 测试技术
基于Java的毕业设计选题系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的毕业设计选题系统的设计与实现(源码+lw+部署文档+讲解等)
32 0
基于Java的毕业设计选题系统的设计与实现(源码+lw+部署文档+讲解等)
|
21天前
|
JavaScript Java 测试技术
基于Java的数学竞赛网站的设计与实现(源码+lw+部署文档+讲解等)
基于Java的数学竞赛网站的设计与实现(源码+lw+部署文档+讲解等)
21 0
|
4月前
|
存储 Java 索引
从零开始学习 Java:简单易懂的入门指南之Collection集合及list集合(二十一)
从零开始学习 Java:简单易懂的入门指南之Collection集合及list集合(二十一)
|
4月前
|
存储 安全 Java
从零开始学习 Java:简单易懂的入门指南之泛型及set集合(二十二)
从零开始学习 Java:简单易懂的入门指南之泛型及set集合(二十二)
|
10月前
|
Java
【JavaSE】Java基础语法(三十三):File 一文详解
1. File类概述和构造方法 File类介绍 它是文件和目录路径名的抽象表示 文件和目录是可以通过File封装成对象的 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也
|
8月前
|
Java 程序员 数据安全/隐私保护
重温经典《Thinking in java》第四版之第六章 访问权限控制(三十六)
重温经典《Thinking in java》第四版之第六章 访问权限控制(三十六)
48 0
|
9月前
|
算法 安全 Java
重温经典《Thinking in java》第四版之第二章 一切都是对象(十三)
重温经典《Thinking in java》第四版之第二章 一切都是对象(十三)
29 0
|
10月前
|
搜索推荐 Java 索引
【JavaSE】Java基础语法(二十三):递归与数组的高级操作
1. 递归 1.1 递归 递归的介绍 以编程的角度来看,递归指的是方法定义中调用方法本身的现象 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解 递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
|
10月前
|
存储 Java 编译器
【JavaSE】Java(五十):核心要点
1. JDK 和 JRE 有什么区别 JDK(Java Development Kit)和 JRE(Java Runtime Environment)是两个不同的软件包。它们共同提供了 Java 开发和运行时环境,但在功能和用途上存在一些区别。 JRE 包含 Java 运行时环境,它只用于执行 Java 应用程序,而没有提供任何开发工具。JRE 包括 JVM(Java 虚拟机)、Java 标准类库、Java 插件等组件,用户可以利用 JRE 去运行已经编写好的 Java 应用程序。 JDK 则是 Java 开发工具包,它除了包括 JRE 中的组件外,还提供了一系列的开发工具,例如编译器 j