当前位置: 首页 > 知识库问答 >
问题:

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

冉高寒
2023-03-14

我有一个基于时间戳对对象进行排序的场景。课程如下:

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
}

对于一个员工来说,有2种可能1、它会有一个地址列表。2.地址列表可以为空

address类有一个字段typeOfResidence,它可以有诸如Residence、Office、ForeignHome之类的值。

每个员工都可以有地址列表,一个地址是住宅,另一个是办公室等。可以有多个居住地址,但只能有一个办公地址。

我想根据地址的起始日期对员工列表进行排序,地址类型=办公室。

我写了以下代码:

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();
}

不知何故,这似乎不起作用。员工没有分类。请帮我使它工作。

共有3个答案

璩正志
2023-03-14

你的问题是:

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

这不是就地排序。收集正在创建一个新的列表实例,该实例从未被分配给变量或返回-该实例被简单地创建,然后立即难以辨认的垃圾回收机制。

东郭自珍
2023-03-14

如果需要就地排序,可以使用集合。排序,而不是流。

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

类似地,null-过滤问题可以通过以下方式解决:

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

(顺便说一句,GetLateStatAddressByType可能是Employee的一个实例方法)

陆浩博
2023-03-14

方法不会改变输入列表

如果需要排序列表

像这样的事情应该做:

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());
}

您可能需要添加一些处理,用于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());

 类似资料:
  • 问题内容: 我有一个Java对象列表,希望根据多个字段进行排序。 是否可以使用或接口根据多个字段对列表进行排序?我看到的所有示例仅根据一个领域进行排序。换句话说,可以按“校园”或“教师”或“建筑”进行排序。我想按“校园”,“教师”,“建筑”(因为它在SQL中存在)进行排序 问题答案: 您的比较器如下所示: 基本上,只要到目前为止已比较的属性相等(),它就会继续比较类的每个连续属性。

  • Employee是上面定义的类之一,Address是Employee字段之一的数据类型之一。列表需要根据员工的字段中的进行排序。 这可以通过编写自定义比较器来完成。我正在寻找一种使用JavaLambda进行排序并获得排序列表的方法?

  • 我有一个假设 我的目的是以循环的方式基于来订购它。 输入: SortedList:

  • 问题内容: 假设有一个Obj类 并且您有一个实例列表,即。 现在,如何在Java8中使用过滤条件从流中找到列表中的对象的int字段值的总和(例如,对于object ,条件为)? 问题答案: 你可以做 或(使用方法参考)

  • 问题内容: 我的清单包含大小等的集合。我尝试这样做,但似乎不起作用。 我想要的最终结果是。 我可以尝试添加在所有的元素和那种出来再做出新的的。但是,有某种班轮吗? 更新: 这可行,但是可以简化吗? 问题答案: @Eugene的回答很甜蜜,因为番石榴很甜。但是,如果您碰巧在类路径中没有番石榴,这是另一种方式: 首先,我将所有集合映射到一个流中,然后对所有元素进行排序,最后,将整个排序后的流收集到集合

  • 假设有一个类Obj 并且您有一个实例列表,即。 现在,我如何在Java8中用流找到来自列表中对象的int字段值的和(例如,对于对象,标准是)?