MST

星途 面试题库

面试题:自定义对象在Java Set集合中的高效使用及内存优化

你需要将自定义的对象放入Set集合中,要求在保证元素唯一性的同时,尽可能提高集合操作的效率,并减少内存消耗。请详细描述如何为自定义对象实现合适的equals()和hashCode()方法,以确保其在Set集合中的高效使用。此外,讨论在高并发环境下,如何对Set集合进行操作以保证数据的一致性和性能,比如如何使用ConcurrentHashMap来构建线程安全的Set集合。
14.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. 为自定义对象实现合适的 equals()hashCode() 方法

  • equals() 方法
    • 首先,检查传入对象是否为 this 本身,如果是则返回 true,这是一个快速短路的优化。
    • 然后,检查传入对象是否为 null 或者是否与当前对象属于不同的类,如果是则返回 false
    • 接着,将传入对象强制转换为当前类的类型(前提是前面的类检查通过)。
    • 最后,比较对象中所有参与唯一性判断的关键属性。例如,如果自定义类 Personnameage 两个属性决定唯一性,代码如下:
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Person person = (Person) o;
    return age == person.age && Objects.equals(name, person.name);
}
  • hashCode() 方法
    • 一个好的 hashCode() 方法应该尽可能地为不同的对象返回不同的哈希值,以减少哈希冲突。
    • 可以使用 Objects.hash() 方法,传入所有参与唯一性判断的属性。对于上述 Person 类:
@Override
public int hashCode() {
    return Objects.hash(name, age);
}
  • 另一种常见的手动计算方式是基于质数(如 31):
@Override
public int hashCode() {
    int result = 17;
    result = 31 * result + (name != null? name.hashCode() : 0);
    result = 31 * result + age;
    return result;
}

2. 在高并发环境下对 Set 集合进行操作

  • 使用 ConcurrentHashMap 构建线程安全的 Set 集合
    • ConcurrentHashMap 本身不是 Set,但可以用来构建线程安全的 Set。可以利用 ConcurrentHashMapKey 唯一性来实现类似 Set 的功能。
    • 例如,创建一个基于 ConcurrentHashMap 的线程安全 Set
import java.util.concurrent.ConcurrentHashMap;

public class ThreadSafeSet<E> {
    private final ConcurrentHashMap<E, Boolean> map = new ConcurrentHashMap<>();

    public boolean add(E e) {
        return map.putIfAbsent(e, true) == null;
    }

    public boolean remove(E e) {
        return map.remove(e) != null;
    }

    public boolean contains(E e) {
        return map.containsKey(e);
    }
}
  • 数据一致性ConcurrentHashMap 采用了分段锁等机制,在高并发情况下可以保证数据的一致性。对于 putIfAbsentremove 等操作,它们都是原子性的,所以在多线程环境下能正确地维护集合的状态。
  • 性能ConcurrentHashMap 的分段锁机制允许多个线程同时访问不同的段,减少了锁竞争,从而提高了性能。相比传统的 Hashtable(全表锁),在高并发场景下性能有显著提升。在构建线程安全 Set 时,利用 ConcurrentHashMap 的这些特性,可以保证在高并发下的高效操作。