Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java8中,首先对整数列表进行排序,然后按可除10进行排序_Java_List_Sorting_Collections_Comparator - Fatal编程技术网

在Java8中,首先对整数列表进行排序,然后按可除10进行排序

在Java8中,首先对整数列表进行排序,然后按可除10进行排序,java,list,sorting,collections,comparator,Java,List,Sorting,Collections,Comparator,我有一个包含{3,10,17,9,20,15,40,30,55}的arraylist,所以我想对这个方法进行排序,这样所有可被10个值整除的值在排序后的排序列表中都排在最后。 i、 e.o/p应该是这样:{3,9,15,17,55,10,20,30,40} 我已尝试使用以下代码,但a我无法成功整理此列表 List<Integer> list = Arrays.asList(3,10,17,9,20,55,40,30); list.stream().sorted(((Comparat

我有一个包含{3,10,17,9,20,15,40,30,55}的arraylist,所以我想对这个方法进行排序,这样所有可被10个值整除的值在排序后的排序列表中都排在最后。 i、 e.o/p应该是这样:{3,9,15,17,55,10,20,30,40}

我已尝试使用以下代码,但a我无法成功整理此列表

List<Integer> list = Arrays.asList(3,10,17,9,20,55,40,30);

list.stream().sorted(((Comparator<Integer>) (v1, v2) -> Integer.compare(v1, v2))).sorted((Comparator<Integer>) (v1, v2) -> v1 % 10 == 0 ? 0 : -1).forEach(System.out::println);
List List=Arrays.asList(3,10,17,9,20,55,40,30);
list.stream().sorted((比较器)(v1,v2)->Integer.compare(v1,v2)).sorted((比较器)(v1,v2)->v1%10==0?0:-1.forEach(系统输出::println);
上述代码的输出为: 55 17 9 3. 10 20 30 四十


谢谢,

看起来您希望在逻辑上将数字分成两组,并分别对每组进行排序

您可以根据除以10的标准拆分列表,并分别对两个子列表执行排序,或者使用单个
比较器
检查两个比较的数字是否属于同一组,以获得相同的结果:

  • 如果他们没有,根据小组决定哪一个应该先来
  • 如果他们这样做了,则在他们的组内按其值进行比较

    list.stream()
        .sorted((v1, v2) -> {
                    if (v1 % 10 == 0) {
                        if (v2 % 10 == 0)
                            return Integer.compare(v1, v2); // both are divisible by 10 
                                                            // sort by value
                        else
                            return 1; // only v1 is divisible by 10, should come after v2
                    } else {
                        if (v2 % 10 != 0)
                            return Integer.compare(v1, v2); // both are not divisible by 10
                                                            // sort by value
                        else
                            return -1; // only v2 is divisible by 10, should come after v1
                    }
    
            })
        .forEach(System.out::println);
    
输出:

3
9
17
55
10
20
30
40

要实现这一点,您需要:

  • 首先将列表分为两个列表,其中一个列表中的数字可以被
    10
    ,第二个是与那些不是的人
  • 然后把它们分开分类
  • 最后将第一个附加到第二个
这是您的代码应该如何编写的:

List<Integer> dividedBy10 = list.stream()
    .filter(p -> p % 10 == 0).collect(Collectors.toList());
Collections.sort(dividedBy10);

List<Integer> others = list.stream()
    .filter(p -> p % 10 != 0).collect(Collectors.toList());
Collections.sort(others);

//Then append the first list to the sorted one
others.addAll(dividedBy10);
List dividedBy10=List.stream()
.filter(p->p%10==0).collect(collector.toList());
Collections.sort(dividedBy10);
List others=List.stream()
.filter(p->p%10!=0).collect(collector.toList());
集合。排序(其他);
//然后将第一个列表附加到已排序的列表
其他。添加全部(除以10);
编辑:

或者,就像建议的那样,您可以对原始列表进行排序,然后将其过滤到列表中,并在以后附加这两个列表:

Collections.sort(list);

List<Integer> dividedBy10 = list.stream()
    .filter(p -> p % 10 == 0).collect(Collectors.toList());

List<Integer> others = list.stream()
    .filter(p -> p % 10 != 0).collect(Collectors.toList());
others.addAll(dividedBy10);
Collections.sort(列表);
List dividedBy10=List.stream()
.filter(p->p%10==0).collect(collector.toList());
List others=List.stream()
.filter(p->p%10!=0).collect(collector.toList());
其他。添加全部(除以10);

需要一次分拣:

list.stream().sorted(((Comparator<Integer>) (v1, v2) -> {

    // if both are divisible by 10, you sort them with their order natural
    if (v1 % 10 == 0 && v2 % 10 == 0) {
       return Integer.compare(v1, v2);
    }

    // if only the first argument is divisible by 10, it is always at the end
    else if (v1 % 10 == 0) {
      return 1;
    }       

    // if only the second argument is divisible by 10, it is always at the end
    else if (v2 % 10 == 0) {
      return -1;
    }

    // in other cases, you sort by natural order
    return Integer.compare(v1, v2);
}))
    .forEach(System.out::println);
list.stream(){
//如果两者都可以被10整除,则按其自然顺序进行排序
如果(v1%10==0&&v2%10==0){
返回整数。比较(v1,v2);
}
//如果只有第一个参数可以被10整除,那么它总是在末尾
否则如果(v1%10==0){
返回1;
}       
//如果只有第二个参数可以被10整除,那么它总是在末尾
否则如果(v2%10==0){
返回-1;
}
//在其他情况下,按自然顺序排序
返回整数。比较(v1,v2);
}))
.forEach(System.out::println);
以下是输出:

3917551003040


目前,你正在否定那些不能被10整除的数字,作为一种先把它们弄出来的技巧。但这将颠倒这些数字的顺序,它们将占到您的输出

在比较可被10整除的数字时,您需要更加小心,这样比较器对它们的排名就会低于其他数字。类似这样的方法会奏效:

list.stream().sorted(((Comparator<Integer>) (v1, v2) -> {
    if (v1 % 10 == 0 && v2 % 10 == 0) {
        return Integer.compare(v1, v2);
    } else if (v1 % 10 == 0) {
        // v2 is effectively larger
        return -1;
    } else if (v2 % 10 == 0) {
        // v1 is effectively larger
        return 1;
    }
    return Integer.compare(v1, v2);
}))/*etc*/
list.stream(){
如果(v1%10==0&&v2%10==0){
返回整数。比较(v1,v2);
}否则如果(v1%10==0){
//v2实际上更大
返回-1;
}否则如果(v2%10==0){
//v1实际上更大
返回1;
}
返回整数。比较(v1,v2);
}))/*等*/

您只有三个返回值:

  • Integer。比较(a,b)
    如果两个值都可以被10整除,而不是
  • >0
    如果第一个值可被10整除
  • <0
    其他

或者如果您喜欢不可读的代码

list.sort((a, b) -> (a % 10 == 0) == (b % 10 == 0) ? a.compareTo(b) : a % 10 == 0 ? 1 : -1);

有两件事需要知道

首先,当您知道自Java5以来,
Boolean
值具有可比性时,排序时按特定谓词进行分组非常容易。所以你可以用

Comparator.comparing(i -> i%10==0)
将可除以10的数排序到最后

其次,您可以使用
然后比较
来链接比较器,这样根据第一个比较器相等的元素将根据下一个比较器进行排序

同时,操作变得更加简单

List<Integer> list = Arrays.asList(3,10,17,9,20,55,40,30);

list.stream()
    .sorted(Comparator.comparing((Integer i) -> i%10==0)
                      .thenComparing(Comparator.naturalOrder()))
    .forEach(System.out::println);

不过,如果适用,我更喜欢重用已经存在的比较器
comparator.naturalOrder()

比较器不是对称的,即30>31,但31>30,但这不能正确排序可被10整除的数字。例如,两者都可以被10整除的情况应称为正常情况。compare@Bathsheba真的很抱歉。这个问题我读得很差,不用担心。顺便说一下,我们的具体退货1和退货-1案例有所不同。谁是对的?;-)如果您对原始列表进行排序,那么这不会在以后保存您的两个排序吗?不过我还是喜欢这个主意,并给了你另外一个:)@davidxxx::绝对不是。你想保持分段的升序,天哪。我原以为他会得到的。真的不好读这个问题。对不起,芭丝谢芭。是的,我更喜欢你的方式,而不是我的方式。拥有向上投票权。
Integer.compare(a,b)
“返回的值的权重为1”。请看方法comper(int,int)只返回0,1,-1。这是一个特定实现的源代码。如果文档中没有说明保证只获取
0
1
-1
,则不保证。因此,实现可以随时更改。或者JVM可能会用一条内在的CPU指令来替换此方法的调用,而不一定只返回这三个值中的一个。清楚地说“0;…小于0;…大于
list.sort((a, b) -> (a % 10 == 0) == (b % 10 == 0) ? a.compareTo(b) : a % 10 == 0 ? 1 : -1);
Comparator.comparing(i -> i%10==0)
List<Integer> list = Arrays.asList(3,10,17,9,20,55,40,30);

list.stream()
    .sorted(Comparator.comparing((Integer i) -> i%10==0)
                      .thenComparing(Comparator.naturalOrder()))
    .forEach(System.out::println);
list.stream()
    .sorted(Comparator.comparing((Integer i) -> i%10==0)
                      .thenComparingInt(i -> i))
    .forEach(System.out::println);