Home > Software engineering >  Java 11 Stream to sort a list of object and add sequence based on sorting
Java 11 Stream to sort a list of object and add sequence based on sorting

Time:02-15

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

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. I tried a messed up code here, can someone please help me.

userInformations.stream()
        .filter(c-> c.getReferringDepartment().equalsIgnoreCase(referralReq.getReferringDepartment()))
        .sorted(Comparator.comparing(SIUInformation::getCreatedDate))
        .forEach(f -> f.setReferralSeqNumber());

So output should be for each department, sequence number should be incremented based on the number of entries using the created date.

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

CodePudding user response:

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?

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. 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.
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.

CodePudding user response:

Streams don't track the number of items that they have processed. 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));

CodePudding user response:

You can't really set the sequence number until all is sorted. So imo, there is not much point in using streams. 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    "");
}
  • Related