如何在将子项目分组在一起的多个元素上对Vector <Vector <String >>进行排序?

时间:2019-11-15 18:48:47

标签: java arrays sorting vector

因此,我从REST API返回JSON数据,该数据已经按日期字段进行了排序,然后将其添加到JTable中使用的Vector>中。我需要将具有相同5位数字键的项目分组在一起,然后按附加的标识符desc顺序(3,2,1)进行排序,其中日期决定下一个5位数字键。

例如:

[[28696, 2, 11/15/19 17:57]]
[[28696, 1, 11/15/19 17:56]]
[[00972, 2, 11/15/19 17:55]]
[[28696, 3, 11/15/19 17:54]]
[[00972, 1, 11/15/19 17:53]]

应该是

[[28696, 3, 11/15/19 17:54]]
[[28696, 2, 11/15/19 17:57]]
[[28696, 1, 11/15/19 17:56]]
[[00972, 2, 11/15/19 17:55]]
[[00972, 1, 11/15/19 17:53]]

看到28696是该组中的第一个项目,是整个数据集中的最新项目。

1 个答案:

答案 0 :(得分:2)

单个sort操作无法实现您想要的。相反,您可以使用流来满足对分组,对组进行排序以及对组内的数据进行排序的要求。

首先请注意,我将您的List<List<String>>转换为List<Data>(按照Max Vollmer的建议),以使其更易于使用和理解。如果您确实需要将其作为List,则可以将Data替换为List<String>,并将Data.get??()替换为List.get(?)

public static void main(String[] args) throws IOException, TransformerException {
    List<Data> list = Arrays.asList( //
            new Data("28696", "2", "11/15/19 17:57"), //
            new Data("28696", "1", "11/15/19 17:56"), //
            new Data("00972", "2", "11/15/19 17:55"), //
            new Data("28696", "3", "11/15/19 17:54"), //
            new Data("00972", "1", "11/15/19 17:53"));

    Comparator<Data> sortByTimestamp = Comparator.comparing(Data::getTimestamp).reversed();
    Comparator<Data> sortByOccurrence = Comparator.comparing(Data::getOccurrence).reversed();

    // LinkedHashMap keeps the insertion order
    Collector<Data, ?, LinkedHashMap<String, List<Data>>> groupByIdKeepInsertOrder
            = Collectors.groupingBy(Data::getId, LinkedHashMap::new, Collectors.toList());

    List<Data> result = list.stream()
            .sorted(sortByTimestamp) // sort all data by timestamp, if it's already sorted by timestamp you can skip this
            .collect(groupByIdKeepInsertOrder) // group them by id keeping the timestamp order
            .values().stream() // stream the lists of data grouped together
            .peek(l -> l.sort(sortByOccurrence)) // sort each list of data by occurrence
            .flatMap(Collection::stream) // flatten the lists into a single stream
            .collect(Collectors.toList()); // collect all Data into a single list

    System.out.println(result);
    // [[28696, 3, 11/15/19 17:54],
    //  [28696, 2, 11/15/19 17:57],
    //  [28696, 1, 11/15/19 17:56],
    //  [00972, 2, 11/15/19 17:55],
    //  [00972, 1, 11/15/19 17:53]]
}

private static class Data {
    private final String id;
    private final String occurrence;
    private final String timestamp;

    public Data(String id, String occurrence, String timestamp) {
        this.id = id;
        this.occurrence = occurrence;
        this.timestamp = timestamp;
    }

    public String getId() { return id; }
    public String getOccurrence() { return occurrence; }
    public String getTimestamp() { return timestamp; }
    @Override public String toString() { return "[" + id + ", " + occurrence + ", " + timestamp + "]";}
}