You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Stream操作嵌套自定义类:查询指定手机号的学生

Java Stream 筛选学生手机号问题解决方案

需求说明

现有包含自定义Address类和MobileNumber类的Student对象列表,每个Student实例持有一个MobileNumber列表,需实现两个筛选需求:

  • 筛选出拥有手机号"3333"的所有学生
  • 筛选出同时拥有手机号"1233"和"1234"的所有学生

原代码问题分析

  1. 第一个需求的实现中,forEach(student -> student.getName())仅调用了获取姓名的方法,未对筛选结果进行收集或输出,无法得到有效结果。
  2. 第二个需求的实现逻辑错误:anyMatch中判断单个手机号同时等于"1233"和"1234",这在逻辑上不可能成立,导致筛选结果为空。

正确实现代码

完整可运行代码

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class StreamsGalore {
    public static void main(String[] args) {

        Student student1 = new Student("Jayesh", 20, new Address("1234"),
                Arrays.asList(new MobileNumber("1233"), new MobileNumber("1234")));

        Student student2 = new Student("Khyati", 20, new Address("1235"), Arrays
                .asList(new MobileNumber("1111"), new MobileNumber("3333"), new MobileNumber("1233")));

        Student student3 = new Student("Jason", 20, new Address("1236"),
                Arrays.asList(new MobileNumber("3333"), new MobileNumber("4444")));

        List<Student> students = Arrays.asList(student1, student2, student3);

        /*****************************************************
         * 需求1:获取所有拥有手机号"3333"的学生
         *****************************************************/
        List<Student> studentsWith3333 = students.stream()
                .filter(student -> student.getMobileNumbers().stream()
                        .anyMatch(mobile -> mobile.getNumber().equals("3333")))
                .collect(Collectors.toList());

        System.out.println("拥有手机号3333的学生:");
        studentsWith3333.forEach(System.out::println);

        /*****************************************************
         * 需求2:获取同时拥有手机号"1233"和"1234"的学生
         *****************************************************/
        // 先定义目标手机号集合
        Set<String> targetNumbers = Set.of("1233", "1234");
        List<String> studentsWithBothNumbers = students.stream()
                .filter(student -> {
                    // 提取当前学生的手机号集合
                    Set<String> studentNumbers = student.getMobileNumbers().stream()
                            .map(MobileNumber::getNumber)
                            .collect(Collectors.toSet());
                    // 检查是否包含所有目标手机号
                    return studentNumbers.containsAll(targetNumbers);
                })
                .map(Student::getName)
                .collect(Collectors.toList());

        System.out.println("\n同时拥有手机号1233和1234的学生姓名:");
        System.out.println(studentsWithBothNumbers);
    }
}

class Address {
    private String zipcode;

    public Address(String zipcode) {
        this.zipcode = zipcode;
    }

    public String getZipcode() {
        return zipcode;
    }

    public void setZipcode(String zipcode) {
        this.zipcode = zipcode;
    }

    @Override
    public String toString() {
        return "Address{" + "zipcode='" + zipcode + '\'' + '}';
    }
}

class MobileNumber {
    private String number;

    public MobileNumber(String number) {
        this.number = number;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @Override
    public String toString() {
        return "MobileNumber{" + "number='" + number + '\'' + '}';
    }
}

class Student {
    private String name;
    private int age;
    private Address address;
    private List<MobileNumber> mobileNumbers;

    public Student(String name, int age, Address address, List<MobileNumber> mobileNumbers) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.mobileNumbers = mobileNumbers;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Address getAddress() {
        return address;
    }

    public List<MobileNumber> getMobileNumbers() {
        return mobileNumbers;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public void setMobileNumbers(List<MobileNumber> mobileNumbers) {
        this.mobileNumbers = mobileNumbers;
    }

    @Override
    public String toString() {
        return "Student{" + "name='" + name + '\'' + ", age=" + age + ", address=" + address
                + ", mobileNumbers=" + mobileNumbers + '}';
    }
}

代码说明

  1. 需求1实现:

    • 使用stream().filter()结合anyMatch()判断学生的手机号列表中是否存在"3333"
    • 用collect(Collectors.toList())收集筛选后的学生对象,方便后续输出或使用
  2. 需求2实现:

    • 先创建目标手机号的Set集合targetNumbers
    • 对每个学生,提取其所有手机号转为Set集合
    • 使用containsAll()方法判断学生的手机号集合是否包含所有目标号码,确保同时拥有两个手机号

内容的提问来源于stack exchange,提问作者LittleZoski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:25:43