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