简体   繁体   English

Java中基于动态串行有序输入流对数据进行排序和分区

[英]sorting and partitioning data based on dynamic serial ordered input stream in java

I want to sort elements and group them as follows, How shall I achieve that using java streams sort, group and partition by. 我想按以下方式对元素进行排序和分组,如何使用java流进行排序,分组和分区依据。

The input is comming in streams that means after getting the below input after sometime the input like A16,17 may come the data structure must reorganize and regroup. 输入以流形式进来,这意味着在获得以下输入之后,有时A16,17之类的输入可能会出现数据结构必须重新组织和重新组合的情况。

Input A10, A4, A11, A3, A12,A15 ....B19,B2,B20... 输入A10,A4,A11,A3,A12,A15 .... B19,B2,B20 ...

Output A3-A4,A10-A12,A15,B2,B19-B20. 输出A3-A4,A10-A12,A15,B2,B19-B20。

I could able to sort as below 我可以排序如下

array.sort(Comparator   .comparing(...)
                                .thenComparing(Comparator.comparing(...)));

but not sure how to partition and regroup for chaning input using streams in most optimised way. 但不确定如何使用流以最优化的方式对输入进行分区和重组。

 array.stream().collect(Collectors.partitionBy(...))

What should be the logic in function for partition by in above in order to achieve serial order grouping ? 为了实现串行顺序分组,在上面进行分区的功能中的逻辑应该是什么?

You can do easily if you write your own Comparator and your own Collector , making use of Java8 Stream interface: 如果您使用Java8 Stream接口编写自己的ComparatorCollector ,则可以轻松实现:

array.stream().sorted(new MyComparator()).collect(new MyCollector());

The Comparator is plain easy to write: Comparator器很容易编写:

class MyComparator implements Comparator<String> {

    @Override
    public int compare(String s1, String s2) {
        if(s1.substring(0, 1).compareTo(s2.substring(0,1)) < 0) {
            return -1;
        } else if (s1.substring(0, 1).compareTo(s2.substring(0,1)) > 0) {
            return 1;
        } else { //first char is equal
            if(Integer.parseInt(s1.substring(1, s1.length())) < Integer.parseInt(s2.substring(1, s2.length()))) {
                return -1;
            } else if (Integer.parseInt(s1.substring(1, s1.length())) > Integer.parseInt(s2.substring(1, s2.length()))) {
                return 1;
            }
        }
        return 0;
    }
}

It basically checks for the letter at the beginning, and then checks for the numbers afterwards. 它基本上在开头检查字母,然后在后面检查数字。 Trying to use natural alphabetical order will put your A10, A11 ... before your A2,A3 ... because 1<2 . 尝试使用自然字母顺序会将A10, A11 ...放在A2,A3 ...之前A2,A3因为1<2

I'm leaving the Collector intentionally unwritten for you to do that part, as it is an interesting exercise. 我故意不让Collector编写该部分,因为这是一个有趣的练习。

But if you don't want to use a Collector because you find it too hard, you can always use the newly ordered List to grab its elements two by two and create another List containing the result you are looking for. 但是,如果您由于发现它太难而不想使用Collector ,则始终可以使用新排序的List来两两地获取其元素,并创建另一个包含要查找的结果的List

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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