简体   繁体   English

java 8 stream用于根据特定字段对对象列表进行排序

[英]java 8 stream for sorting a list of objects based on particular field

I have a scenario to sort the objects based on timestamp. 我有一个场景来根据时间戳对对象进行排序。 The classes are as follows: 课程如下:

class Employee 
{
    private String name;
    private List<Address> addresses;

    //...
    //Getters and setters for all fields
}

public class Address
{
    private String city;
    private Timestamp startDate;
    private Timestamp endDate;
    private String typeOfResidence;

    //...
    //Getters and setters for all the fields
}

For an employee, there are 2 possibilities 1. it will have a list of address. 对于一名员工,有两种可能性1.它将有一个地址列表。 2. the list of address can be null 2.地址列表可以为空

The address class has a field typeOfResidence which can have values such as Residence, Office, ForeignHome. 地址类有一个字段typeOfResidence ,它可以包含Residence,Office,ForeignHome等值。

Each Employee can have list of address, one address will be Residential, other Office and so on. 每个Employee都可以有地址列表,一个地址是住宅,其他办公室等等。 There can be multiple Residential addresses but only one Office address. 可以有多个住宅地址,但只有一个Office地址。

I want to sort the list of employees based on startDate of Address whose typeOfResidence=Office. 我想根据typeOfResidence = Office的startDate of Address对员工列表进行排序。

I have written the following code: 我写了以下代码:

private void sortEmployeeListBasedOnStartDate(List<Employee> employeeList)
{
    Comparator<Address> byTimeStamp = Comparator.comparing(
        Address::getStarteDate,
        (ts1, ts2) -> ts1.toGregorianCalendar().compareTo(ts2.toGregorianCalendar())
    );

    employeeList.stream()
        .map(x -> getLatestAddressByType(x, "Office"))
        .filter(y -> y!=null)
        .sorted(byTimeStamp.reversed())
        .collect(Collectors.toList());
}

public Address getLatestAddressByType(Employee employee, String type)
{
    if(role != null && brokerageManagedProposalType != null)
    {
         return getUserAddress(employee).stream()
            .filter(address-> address.getTypeOfResidence().equals(type))
            .findFirst()
            .orElse(null);
    }
    return null;
}

public List<Address> getUserAddress(Employee employee)
{
    if (!NullChecker.isNull(employee) && !NullChecker.isNull(employee.getAddress()))
    {
        return employee.getAddress();
    }
    return Collections.emptyList();
}

Somehow this does not seem to be working. 不知怎的,这似乎不起作用。 The employees are not sorted. 员工没有分类。 Please help me to make it working. 请帮我把它搞定。

Your sortEmployeeListBasedOnStartDate method doesn't mutate the input List<Employee> . 您的sortEmployeeListBasedOnStartDate方法不会改变输入List<Employee> It creates a new sorted List<Address> , which you do nothing with. 它会创建一个新的已排序的List<Address> ,您无需执行任何操作。

If you want a sorted List<Employee> , you shouldn't be mapping the Employee s to Address es. 如果需要排序的List<Employee> ,则不应将Employee映射到Address es。 You should produce a sorted List<Employee> and return that List . 您应该生成一个已排序的List<Employee>并返回该List

Something like this should do: 这样的事情应该做:

private List<Employee> sortEmployeeListBasedOnStartDate(List<Employee> employeeList)
{
    Comparator<Address> byTimeStamp = Comparator.comparing(
        Address::getStarteDate,
        (ts1, ts2) -> ts1.toGregorianCalendar().compareTo(ts2.toGregorianCalendar())
    );

    return employeeList
        .stream()
        .sorted((e1,e2)->byTimeStamp.compare(getLatestAddressByType(e2, "Office"),getLatestAddressByType(e1, "Office")))
        .collect(Collectors.toList());
}

You might have to add some handling for the case where getLatestAddressByType() returns null : 您可能必须为getLatestAddressByType()返回null的情况添加一些处理:

    return employeeList
        .stream()
        .filter(e->getLatestAddressByType(e, "Office") != null)
        .sorted((e1,e2)->byTimeStamp.compare(getLatestAddressByType(e2, "Office"),getLatestAddressByType(e1, "Office")))
        .collect(Collectors.toList());

If you want in-place sorting, you can use Collections.sort instead of streams. 如果要进行就地排序,可以使用Collections.sort而不是stream。

Collections.sort(employeeList, 
    (e1,e2) -> byTimeStamp.compare(
        getLatestAddressByType(e2, "Office"),
        getLatestAddressByType(e1, "Office") );

Similarly, the null -filtering issue can be solved in-place as follows: 同样, null -filtering问题可以就地解决,如下所示:

employeeList.removeIf(e -> getLatestAddressByType(e, "Office") == null);

(btw, getLatestAddressByType should probably be an instance method of Employee ) (顺便说一句, getLatestAddressByType应该是Employee的实例方法)

Your problem is here: 你的问题在这里:

employeeList.stream()
    .map(x -> getLatestAddressByType(x, "Office"))
    .filter(y -> y!=null)
    .sorted(byTimeStamp.reversed())
    .collect(Collectors.toList());

This is not an in-place sort. 这不是就地排序。 The values in employeeList remain exactly the same. employeeList的值保持完全相同。 collect is creating a new List instance which is never assigned to a variable or returned - the instance is simply created and then immediately illegible for garbage collection. collect正在创建一个新的List实例,它永远不会分配给变量或返回 - 实例只是简单地创建,然后立即难以收集垃圾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java stream 基于双精度值排序对象 - Java stream sorting objects based on the double value 基于对象列表中List内的字段对对象列表进行排序 - Sorting List of objects based on a field within a List in the List of objects 在Java中按日期字段排序对象列表 - Sorting list of objects by date field in Java GroupBy 和 Stream 根据每个日期 java 列表中特定记录的最大字段过滤 - GroupBy and Stream Filter based on max field for particular record on each date java list 基于自定义参数Java的对象列表排序 - Sorting of List of Objects based on Custom parameter Java 根据对象字段与给定值的绝对差对对象列表进行排序。 (Java) - Sorting a List of Objects based o absolute difference of an Object's field and a given value. (Java) Java 11 Stream 对 object 的列表进行排序并根据排序添加序列 - Java 11 Stream to sort a list of object and add sequence based on sorting Java Stream:按 ZoneDateTime 字段排序 - Java Stream: sorting by ZoneDateTime field 按多个字段排序 Java 对象列表并按特定字段分组 - Sort a list of Java objects by multiple fields and group by a particular field 根据特定的预定义顺序对TreeSet中的对象进行排序 - Sorting objects in a TreeSet based on a particular predefined order
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM