Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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
Java 流排序问题_Java_Sorting_Java 8_Java Stream - Fatal编程技术网

Java 流排序问题

Java 流排序问题,java,sorting,java-8,java-stream,Java,Sorting,Java 8,Java Stream,我有一个要用流排序方法排序的项目列表(MyDetail对象)。对象有3个字段:字段1、字段2、字段3。 我想先按字段3排序,然后按字段2排序,然后按字段1排序,所有的排序顺序都是相反的。 所以我写了一个方法sortMyList 我有一个未分类项目的列表未分类详细信息如下: myDetail1:“20180201”,假,假 myDetail2:“20180101”,假,假 myDetail3:“20180101”,假,真 在sortMyList(unSortedDetails)之后,我希望我的结果

我有一个要用流排序方法排序的项目列表(MyDetail对象)。对象有3个字段:字段1、字段2、字段3。 我想先按字段3排序,然后按字段2排序,然后按字段1排序,所有的排序顺序都是相反的。 所以我写了一个方法sortMyList

我有一个未分类项目的列表未分类详细信息如下: myDetail1:“20180201”,假,假 myDetail2:“20180101”,假,假 myDetail3:“20180101”,假,真

在sortMyList(unSortedDetails)之后,我希望我的结果是myDetail3、myDetail1、myDetail2,但实际结果是myDetail1、myDetail3、myDetail2,为什么

因此,如果我像下面这样为MyDetail实现Comparable,那么它将按预期工作。这太奇怪了。我不明白为什么。谢谢你的帮助

public List<MyDetail> sortMyList(List<MyDetail> unSortedDetails){
    List<MyDetail> myDetails = unSortedDetails
                        .stream().sorted(Comparator.comparing(MyDetail::getField11).reversed()
                                .thenComparing(MyDetail::getField2).reversed()
                                .thenComparing(MyDetail::getField3).reversed())
                        .collect(Collectors.toList());
                        return myDetails;
                        }

                        @Setter
                        @Getter
                        public class MyDetail{
                            String field1;
                            Boolean field2; 
                            Boolean field3; 
                        }



                @Setter
                @Getter
                public class MyDetail implement Comparable<MyDetail>{
                    String field1;
                    Boolean field2; 
                    Boolean field3; 

                        @Override
                        public int compareTo(MyDetail o) {
                            if (this == o || this.equals(o)) return 0;
                            if (field3) return -1;
                            if (o.field3) return 1;
                            if (!field3 && !o.field3 && field2) return -1;
                            if(!field3 && !o.field3 &&!field2 && o.field2) return 1;
                            if(!field3 && !o.field3
                                    &&!field2 && !o.field2){
                                return o.field1.compareTo(field1);
                            }
                            return 0;
}
                }
public List sortMyList(List unSortedDetails){
List myDetails=unSortedDetails
.stream().sorted(Comparator.comparing(MyDetail::getField11).reversed()
.thenComparing(MyDetail::getField2).reversed()
.thenComparing(MyDetail::getField3).reversed())
.collect(Collectors.toList());
返回我的详细信息;
}
@塞特
@吸气剂
公共类MyDetail{
字符串字段1;
布尔域2;
布尔字段3;
}
@塞特
@吸气剂
公共类MyDetail实现可比较{
字符串字段1;
布尔域2;
布尔字段3;
@凌驾
公共整数比较(MYO详细信息){
如果(this==o | | this.equals(o))返回0;
如果(字段3)返回-1;
如果(o.field3)返回1;
如果(!field3&&!o.field3&&field2)返回-1;
如果(!field3&&!o.field3&&!field2&&o.field2)返回1;
如果(!field3&&!o.field3
&&!field2&&!o.field2){
返回o.field1.compareTo(field1);
}
返回0;
}
}

比较器几乎没有问题。首先,每次调用
reversed()
时,您都在反转比较器之前的所有设置

因此,比较器表示(请参见注释中的步骤,
FieldX
简化为
Fx

因此,最终的结果是订单
Field1 DESC,Field2 ASC,Field3 DESC

若要为每个字段指定反转顺序,请通过传递该字段的已反转的比较器,如
。然后比较(comparator.comparing(YourClass::getField).reversed())


下一个问题是比较器使用的字段顺序。在你的问题中,你说:

我想先按字段3排序,然后按字段2排序,然后按字段1排序

但是您的比较器首先检查字段1,然后检查字段2,然后检查字段3(因为您是按照这个顺序通过
添加它们的。然后再比较

您的代码应该更像

Comparator.comparing(MyDetail::getField13).reversed()
          .thenComparing(Comparator.comparing(MyDetail::getField2).reversed())
          .thenComparing(Comparator.comparing(MyDetail::getField1).reversed())
因此,您正在创建
~(F3 ASC),~(F2 ASC),~(F1 ASC)
,结果是
F3 DESC,F2 DESC,F1 DESC


顺便说一句,你可以达到同样的效果

Comparator.comparing(MyDetail::getField3)
          .thenComparing(MyDetail::getField2) 
          .thenComparing(MyDetail::getField1)
          .reversed()
请注意,
compariator.comparing(FunctionToValue)
然后comparing(FunctionToValue)
将为所选值创建递增的比较器

所以前3行构造了描述顺序的比较器
f3asc、F2 ASC、F1 ASC
。反转后

~(F3 ASC,F2 ASC,F1 ASC)
还提供我们所需的
F3 DESC,F2 DESC,F1 DESC

您的
字段*
类型为
字符串
,但您试图在if语句中将它们视为
布尔
条件。哦,对不起,字段3,字段2是布尔的,字段1是字符串,更新了很多!你的解释很清楚。爱死它了!还有一个问题,那么流排序和类上的可比排序,哪种方式更快?我会晚一点投票,但我测试了一下,没有发现两者有多大区别。我现在帮不了你,但这听起来是个有趣的问题。考虑为它创建单独的POST,并包括测试。无论如何,一开始我可能不会为性能而烦恼,因为
Comparable
接口的目的是为元素提供默认顺序,而
Comparator
的目的是让其他人使用任何定制的顺序。我们通常不需要考虑默认订单和用户定义订单的性能,但正如我所说的,这可能是一个有趣的问题,其他人可以回答。你们把事情复杂化了。要使用与所有属性相反的顺序获取比较器,只需为所有属性创建一个比较器并反转最终结果:
comparator.comparing(MyDetail::getField3)。然后comparing(MyDetail::getField2)。然后comparing(MyDetail::getField1)。reversed()
@Holger True,我主要关注于解释问题(误用
reversed
和错误的字段顺序)。但是,尽管您建议的方法是有效的,但IMO使用
thenComparing(reversedComparator)
更容易理解,因此也不太容易出错。无论如何,感谢您指出这一点,它会将您的变体添加到答案中。
Comparator.comparing(MyDetail::getField3)
          .thenComparing(MyDetail::getField2) 
          .thenComparing(MyDetail::getField1)
          .reversed()