java 8 个流,用于根据特定字段对对象列表进行排序
java 8 stream for sorting a list of objects based on particular field
我有一个场景可以根据时间戳对对象进行排序。 class如下:
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
}
对于一个员工,有两种可能
1. 它将有一个地址列表。
2.地址列表可以为空
地址 class 有一个字段 typeOfResidence
,它可以包含 Residence、Office、ForeignHome 等值。
每个Employee
可以有地址列表,一个地址是住宅,另一个是办公室等等。住宅地址可以有多个,办公地址只能有一个。
我想根据 typeOfResidence=Office 的地址的开始日期对员工列表进行排序。
我写了下面的代码:
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();
}
这似乎不起作用。员工没有分类。请帮我让它工作。
您的 sortEmployeeListBasedOnStartDate
方法不会改变输入 List<Employee>
。它会创建一个新的排序 List<Address>
,您无需对其进行任何操作。
如果您想要排序的 List<Employee>
,则不应将 Employee
映射到 Address
。您应该生成 List<Employee>
和 return 的 List
.
应该这样做:
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()
returns null
:
的情况添加一些处理
return employeeList
.stream()
.filter(e->getLatestAddressByType(e, "Office") != null)
.sorted((e1,e2)->byTimeStamp.compare(getLatestAddressByType(e2, "Office"),getLatestAddressByType(e1, "Office")))
.collect(Collectors.toList());
您的问题在这里:
employeeList.stream()
.map(x -> getLatestAddressByType(x, "Office"))
.filter(y -> y!=null)
.sorted(byTimeStamp.reversed())
.collect(Collectors.toList());
这不是就地排序。 employeeList
中的值保持完全相同。 collect
正在创建一个新的 List
实例,该实例从未分配给变量或返回 - 该实例只是简单地创建,然后立即无法辨认以进行垃圾回收。
如果要就地排序,可以使用 Collections.sort
而不是流。
Collections.sort(employeeList,
(e1,e2) -> byTimeStamp.compare(
getLatestAddressByType(e2, "Office"),
getLatestAddressByType(e1, "Office") );
同样,null
-过滤问题可以按如下方式就地解决:
employeeList.removeIf(e -> getLatestAddressByType(e, "Office") == null);
(顺便说一句,getLatestAddressByType
应该是 Employee
的一个实例方法)
我有一个场景可以根据时间戳对对象进行排序。 class如下:
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
}
对于一个员工,有两种可能 1. 它将有一个地址列表。 2.地址列表可以为空
地址 class 有一个字段 typeOfResidence
,它可以包含 Residence、Office、ForeignHome 等值。
每个Employee
可以有地址列表,一个地址是住宅,另一个是办公室等等。住宅地址可以有多个,办公地址只能有一个。
我想根据 typeOfResidence=Office 的地址的开始日期对员工列表进行排序。
我写了下面的代码:
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();
}
这似乎不起作用。员工没有分类。请帮我让它工作。
您的 sortEmployeeListBasedOnStartDate
方法不会改变输入 List<Employee>
。它会创建一个新的排序 List<Address>
,您无需对其进行任何操作。
如果您想要排序的 List<Employee>
,则不应将 Employee
映射到 Address
。您应该生成 List<Employee>
和 return 的 List
.
应该这样做:
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()
returns null
:
return employeeList
.stream()
.filter(e->getLatestAddressByType(e, "Office") != null)
.sorted((e1,e2)->byTimeStamp.compare(getLatestAddressByType(e2, "Office"),getLatestAddressByType(e1, "Office")))
.collect(Collectors.toList());
您的问题在这里:
employeeList.stream()
.map(x -> getLatestAddressByType(x, "Office"))
.filter(y -> y!=null)
.sorted(byTimeStamp.reversed())
.collect(Collectors.toList());
这不是就地排序。 employeeList
中的值保持完全相同。 collect
正在创建一个新的 List
实例,该实例从未分配给变量或返回 - 该实例只是简单地创建,然后立即无法辨认以进行垃圾回收。
如果要就地排序,可以使用 Collections.sort
而不是流。
Collections.sort(employeeList,
(e1,e2) -> byTimeStamp.compare(
getLatestAddressByType(e2, "Office"),
getLatestAddressByType(e1, "Office") );
同样,null
-过滤问题可以按如下方式就地解决:
employeeList.removeIf(e -> getLatestAddressByType(e, "Office") == null);
(顺便说一句,getLatestAddressByType
应该是 Employee
的一个实例方法)