按多个字段对列表进行排序(而不是然后比较)在Java中。

huangapple go评论89阅读模式
英文:

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

问题

现在我有一个对象:

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

我想要按照 'roomId' 对房间列表进行排序,但与此同时,当房间对象的 'roomGroupId' 大于零且具有相同的值时,将它们靠近彼此。
让我给你一些示例:

输入:

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

输出:

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

如上所示,列表按 'roomId' 排序,但 'roomId 4' 和 'roomId 1' 靠在一起,因为它们具有相同的 'roomGroupId'。

英文:

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.

答案1

得分: 1

这没有简单的好解决方法(也许我错了)。

你可以像这样做:

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());
英文:

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

You can do this like this

        TreeMap&lt;Long, List&lt;Room&gt;&gt; roomMap = new TreeMap&lt;&gt;();

        rooms.stream()
             .collect(Collectors.groupingBy(Room::getRoomGroupId))
             .forEach((key, value) -&gt; {
                 if (key.equals(0L)) {
                     value.forEach(room -&gt; 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&lt;Room&gt; result = roomMap.descendingMap()
                                   .entrySet()
                                   .stream()
                                   .flatMap(entry -&gt; entry.getValue()
                                                          .stream())
                                   .collect(Collectors.toList());

答案2

得分: -1

如果你使用Java 8,你可以使用以下类似的代码:

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

如果不是,你应该使用一个比较器:

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

然后像这样使用它

```java
Collections.sort(roomList, new SortRoom());
英文:

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&lt;Room&gt; 
{ 
 
    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()); 

huangapple
  • 本文由 发表于 2020年8月6日 14:01:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63277701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定