Set相关的两道面试题

题目1:在List内去除重复数字值,要求尽量简单

public List duplicateList(List list) {
    HashSet set = new HashSet();
    set.addAll(list);
    return new ArrayList(set);
}
@Test
public void test19() {
    List list = new ArrayList();
    list.add(new Integer(1));
    list.add(new Integer(2));
    list.add(new Integer(2));
    list.add(new Integer(4));
    list.add(new Integer(4));
    List list2 = duplicateList(list);
    for (Object integer : list2) {
        System.out.println(integer);
    }
}

基于Set接口存储的是无序的、不可重复的数据,那么咱们可以把带有重复数据的list传入set中,相当于进行了一次 过滤 操作。

这道题目对list添加的都是Integer类型的元素。但如果添加的是 自定义的类所造的对象 并且还要去除重复的内容,除了要重写equals()方法,还应重写HashCode()方法。

因为:虽然咱们把元素添加到list中了,好像只需要重写equals()方法。但在调用duplicateList()方法时,里面还调用了set的addAll()方法,又因为向Set(主要指:HashSet、LinkedHashSet)中添加数据,其所在的类一定要重写hashCode()方法和equals()方法,所以要重写两个方法。

题目2:以下代码的输出结果

import java.util.Objects;

public class Person {
    int id;
    String name;
    
    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Person() {
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}
public void test43() {
    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); //
}

对于Set存储数据的底层原理考察较大
在这里插入图片描述
对于程序中 set.remove(p1); 操作,因为remove()方法可以返回一个boolean类型的值,大家可以输出其返回值来验证其是否移除成功。

而对于最后运行结果的第三行,出现了两个 Person{id=1001, name='CC'} ,有些同学可能会想:Set存储的不是不可重复的数据吗,这不是两个一样的吗?能想到这个当然很棒,因为是自己理解的成功。但时要知道的是,两个元素实际上并不一样,前面的 Person{id=1001, name='CC'} 是p1这个对象的name属性由AA修改为CC得到的,其hash值和索引位置是按照1001,AA计算得来的。而后一个 Person{id=1001, name='CC'} 是由一个具有1001,CC属性的Person对象,经过计算hash值和索引位置存放的,两者在底层数组中的存放位置本质上是不同的。

简而言之,一个是由AA计算得来,存放到数组中后,修改为CC,而另一个是由CC计算得来,存放到数组中的。

程序输出结果:

[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}]
[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}, Person{id=1001, name='CC'}]
[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}, Person{id=1001, name='CC'}, Person{id=1001, name='AA'}]
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值