简体   繁体   中英

Sort list by multiple fields(not then compare) in java

Now I have an object:

public class Room{
    private long roomId;
    private long roomGroupId;
    private String roomName;
    ... getter 
    ... setter
}

I want sort list of rooms by 'roomId', but in the meantime while room objects has 'roomGroupId' greator than zero and has same value then make them close to each other. Let me give you some example:

input:

[{"roomId":3,"roomGroupId":0},
 {"roomId":6,"roomGroupId":0},
 {"roomId":1,"roomGroupId":1},
 {"roomId":2,"roomGroupId":0},
 {"roomId":4,"roomGroupId":1}]

output:

[{"roomId":6,"roomGroupId":0},
 {"roomId":4,"roomGroupId":1},
 {"roomId":1,"roomGroupId":1},
 {"roomId":3,"roomGroupId":0},
 {"roomId":2,"roomGroupId":0}]

As shown above, the list sort by 'roomId', but 'roomId 4' and 'roomId 1' are close together, because they has the same roomGroupId.

This does not have easy nice solution (maybe I am wrong).

You can do this like this

        TreeMap<Long, List<Room>> roomMap = new TreeMap<>();

        rooms.stream()
             .collect(Collectors.groupingBy(Room::getRoomGroupId))
             .forEach((key, value) -> {
                 if (key.equals(0L)) {
                     value.forEach(room -> roomMap.put(room.getRoomId(), Arrays.asList(room)));
                 } else {
                     roomMap.put(
                         Collections.max(value, Comparator.comparing(Room::getRoomId))
                                    .getRoomId(),
                         value
                             .stream()
                             .sorted(Comparator.comparing(Room::getRoomId)
                                               .reversed())
                             .collect(Collectors.toList())
                     );
                 }
             });

        List<Room> result = roomMap.descendingMap()
                                   .entrySet()
                                   .stream()
                                   .flatMap(entry -> entry.getValue()
                                                          .stream())
                                   .collect(Collectors.toList());

If you're in Java 8, you can use code like this

Collections.sort(roomList, Comparator.comparing(Room::getRoomGroupId)
            .thenComparing(Room::getRoomId));

If not, you should use a comparator

class SortRoom implements Comparator<Room> 
{ 
 
    public int compare(Room a, Room b) 
    { 
        if (a.getRoomGroupId().compareTo(b.getRoomGroupId()) == 0) {
            return a.getRoomId().compareTo(b.getRoomId());
        }
            
        return a.getRoomGroupId().compareTo(b.getRoomGroupId(); 
    } 
} 

and then use it like this

Collections.sort(roomList, new SortRoom()); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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