Java 11 Stream 对对象列表进行排序,并根据排序添加序列
Java 11 Stream to sort a list of object and add sequence based on sorting
我需要根据创建日期字段将序列号添加到对象列表
代码写在Java11。
我有一个如下所示的列表
public class UserInformation {
private String userSeqNumber;
private String userDepartment;
private Date createdDate;
}
我可以按创建日期对列表进行排序,但同时我需要根据创建日期按升序添加 userSequenceNumber。
我在这里尝试了一个混乱的代码,有人可以帮助我吗?
userInformations.stream()
.filter(c-> c.getUserDepartment().equalsIgnoreCase(request.getUserDepartment()))
.sorted(Comparator.comparing(UserInformation::getCreatedDate))
.forEach(f -> f.setUserSeqNumber());
所以输出应该针对每个部门,序列号应该根据使用创建日期的条目数递增。
UserInformation:[{"1","IT",01-01-2022}, {"2","IT",01-02-2022},{"1","OPS",01-01-2022}, {"2,"OPS",01-02-2022}]
可能是我不明白这个问题,因为您的代码示例引用了未知字段 (referringDepartment
、referralSeqNumber
) 和未知 类 (SIUInformation
)但我猜这可能是您或多或少需要的?
userInformations.stream()
.collect(Collectors.groupingBy(UserInformation::getUserDepartment))
.values()
.forEach(listForDepartment -> {
AtomicInteger x = new AtomicInteger(1);
listForDepartment.stream()
.sorted(Comparator.comparing(UserInformation::getCreatedDate))
.forEachOrdered(item -> item.setUserSeqNumber(String.valueOf(x.getAndIncrement())));
});
首先按部门对 UserInformation
对象进行分组(结果为 Map<String List<UserInformation>
),然后循环此操作创建的映射中的值。然后,您使用 sorted()
按 createdDate 对值进行排序(日期比较器默认为升序),然后开始根据元素的顺序填充 userSeqNumber,地图中的每个部门从 1 重新开始。
请注意,我使用 forEachOrdered
而不是 forEach
,因为我明确想记录顺序很重要,即使在这种情况下,如果使用 forEach
也不会破坏代码。
Streams 不跟踪它们已处理的项目数。实现您想要的最简单方法是分两部分完成。
List<UserInformation> sorted = userInformations.stream()
.filter(c-> c.getReferringDepartment().equalsIgnoreCase(referralReq.getReferringDepartment()))
.sorted(Comparator.comparing(SIUInformation::getCreatedDate))
.collect(Collectors.toList());
IntStream.range(0, sorted.size()).forEach(i -> sorted.get(i).setReferralSeqNumber(i));
所有排序完成后才能真正设置序号。因此,imo,使用流没有多大意义。根据现有信息,我将执行以下操作:
userInformation.sort(Comparator
.comparing(UserInformation::getCreatedDate));
// now assign the ids.
int id = 1;
for(UserInformation user : userInformation) {
user.setUserSeqNumber(id++ +"");
}
我需要根据创建日期字段将序列号添加到对象列表 代码写在Java11。 我有一个如下所示的列表
public class UserInformation {
private String userSeqNumber;
private String userDepartment;
private Date createdDate;
}
我可以按创建日期对列表进行排序,但同时我需要根据创建日期按升序添加 userSequenceNumber。 我在这里尝试了一个混乱的代码,有人可以帮助我吗?
userInformations.stream()
.filter(c-> c.getUserDepartment().equalsIgnoreCase(request.getUserDepartment()))
.sorted(Comparator.comparing(UserInformation::getCreatedDate))
.forEach(f -> f.setUserSeqNumber());
所以输出应该针对每个部门,序列号应该根据使用创建日期的条目数递增。
UserInformation:[{"1","IT",01-01-2022}, {"2","IT",01-02-2022},{"1","OPS",01-01-2022}, {"2,"OPS",01-02-2022}]
可能是我不明白这个问题,因为您的代码示例引用了未知字段 (referringDepartment
、referralSeqNumber
) 和未知 类 (SIUInformation
)但我猜这可能是您或多或少需要的?
userInformations.stream()
.collect(Collectors.groupingBy(UserInformation::getUserDepartment))
.values()
.forEach(listForDepartment -> {
AtomicInteger x = new AtomicInteger(1);
listForDepartment.stream()
.sorted(Comparator.comparing(UserInformation::getCreatedDate))
.forEachOrdered(item -> item.setUserSeqNumber(String.valueOf(x.getAndIncrement())));
});
首先按部门对 UserInformation
对象进行分组(结果为 Map<String List<UserInformation>
),然后循环此操作创建的映射中的值。然后,您使用 sorted()
按 createdDate 对值进行排序(日期比较器默认为升序),然后开始根据元素的顺序填充 userSeqNumber,地图中的每个部门从 1 重新开始。
请注意,我使用 forEachOrdered
而不是 forEach
,因为我明确想记录顺序很重要,即使在这种情况下,如果使用 forEach
也不会破坏代码。
Streams 不跟踪它们已处理的项目数。实现您想要的最简单方法是分两部分完成。
List<UserInformation> sorted = userInformations.stream()
.filter(c-> c.getReferringDepartment().equalsIgnoreCase(referralReq.getReferringDepartment()))
.sorted(Comparator.comparing(SIUInformation::getCreatedDate))
.collect(Collectors.toList());
IntStream.range(0, sorted.size()).forEach(i -> sorted.get(i).setReferralSeqNumber(i));
所有排序完成后才能真正设置序号。因此,imo,使用流没有多大意义。根据现有信息,我将执行以下操作:
userInformation.sort(Comparator
.comparing(UserInformation::getCreatedDate));
// now assign the ids.
int id = 1;
for(UserInformation user : userInformation) {
user.setUserSeqNumber(id++ +"");
}