简体   繁体   English

Java 11 Stream 对 object 的列表进行排序并根据排序添加序列

[英]Java 11 Stream to sort a list of object and add sequence based on sorting

I need add sequence number to a list of object based on created date field Code is written in Java 11. I have a list like the below one我需要根据创建日期字段将序列号添加到 object 的列表中 代码写在 Java 11. 我有一个如下所示的列表

public class UserInformation {
    private String userSeqNumber;
    private String userDepartment;
    private Date createdDate;
}

I can sort the list by created date but at the same time i need to add the userSequenceNumber based on the created date in ascending order.我可以按创建日期对列表进行排序,但同时我需要根据创建日期按升序添加 userSequenceNumber。 I tried a messed up code here, can someone please help me.我在这里尝试了一个混乱的代码,有人可以帮助我吗?

userInformations.stream()
        .filter(c-> c.getUserDepartment().equalsIgnoreCase(request.getUserDepartment()))
        .sorted(Comparator.comparing(UserInformation::getCreatedDate))
        .forEach(f -> f.setUserSeqNumber());

So output should be for each department, sequence number should be incremented based on the number of entries using the created date.所以 output 应该是每个部门,序列号应该根据使用创建日期的条目数递增。

UserInformation:[{"1","IT",01-01-2022}, {"2","IT",01-02-2022},{"1","OPS",01-01-2022}, {"2,"OPS",01-02-2022}]

It could be I don't understand the issue because your code example refers to unknown fields ( referringDepartment , referralSeqNumber ) and unknown classes ( SIUInformation ) but I'm guessing this is likely what you more or less need?可能是我不明白这个问题,因为您的代码示例引用了未知字段( referringDepartmentreferralSeqNumber )和未知类( 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())));
         });

First you group the UserInformation objects by department (resulting in Map<String List<UserInformation> ) and then you loop the values in the Map created by this action.首先,您按部门对UserInformation对象进行分组(生成Map<String List<UserInformation> ),然后循环此操作创建的 Map 中的值。 You then sort the values by createdDate using sorted() (Date comparator is by default ascending) and you then start filling in the userSeqNumber according the order of the elements, restarting from 1 for every department in the map.然后,您使用sorted()按 createdDate 对值进行排序(日期比较器默认为升序),然后开始根据元素的顺序填充 userSeqNumber,对于 map 中的每个部门从 1 重新开始。
Note I use forEachOrdered instead of forEach as I explicitly want to document that the order matters, even though in this case, it won't break the code if forEach is used instead.请注意,我使用forEachOrdered而不是forEach ,因为我明确想要记录顺序很重要,即使在这种情况下,如果forEach也不会破坏代码。

Streams don't track the number of items that they have processed. Streams 不跟踪它们已处理的项目数。 The simplest way to achieve what you want is to do it in 2 parts.实现您想要的最简单方法是分两部分进行。

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

You can't really set the sequence number until all is sorted.在所有排序完成之前,您无法真正设置序列号。 So imo, there is not much point in using streams.因此,imo,使用流没有多大意义。 Based on existing information, I would just do the following:根据现有信息,我只会执行以下操作:

userInformation.sort(Comparator
        .comparing(UserInformation::getCreatedDate));
// now assign the ids.
int id = 1;
for(UserInformation user : userInformation) {
    user.setUserSeqNumber(id++ +"");
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM