MST

星途 面试题库

面试题:Java中Stream distinct方法去重原理相关 - 中等难度

请简述Java Stream中distinct方法在基本数据类型流和对象流上去重的原理有何不同。若有一个自定义类User,包含name和age属性,如何使用Stream distinct方法对User对象组成的流进行去重,且仅当name和age都相同时视为重复元素?
17.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. distinct方法在基本数据类型流和对象流上去重原理的不同

  • 基本数据类型流:在基本数据类型流(如IntStreamDoubleStream等)中,distinct方法基于值本身进行去重。基本数据类型的值是直接存储在内存中的,distinct方法通过比较值来判断元素是否重复。例如,在IntStream中,两个int值相等(即数值完全一样)就被视为重复元素,会被去除。
  • 对象流:对于对象流(如Stream<User>),distinct方法默认基于对象的内存地址(即对象的标识)来判断重复。如果两个对象的内存地址相同,就认为它们是重复的。然而,通常情况下,我们希望基于对象的某些属性来判断重复,而不是内存地址。这就需要自定义重复判断逻辑。

2. 对User对象组成的流进行去重(name和age都相同时视为重复元素)

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

class User {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

public class Main {
    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("Alice", 25));
        userList.add(new User("Bob", 30));
        userList.add(new User("Alice", 25));

        List<User> distinctUserList = userList.stream()
               .distinct()
               .collect(Collectors.toList());

        distinctUserList.forEach(user -> System.out.println("Name: " + user.getName() + ", Age: " + user.getAge()));
    }
}

在上述代码中:

  • 首先在User类中重写了equals方法,定义了两个User对象相等的条件是nameage都相同。
  • 同时重写了hashCode方法,以确保在使用distinct方法时,哈希表能够正确地判断对象是否重复。因为distinct方法在内部使用HashSet来实现去重,HashSet依赖hashCodeequals方法来判断元素是否重复。
  • 然后通过Streamdistinct方法对User对象流进行去重,最后收集结果。