Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.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流排序-具有2个或更多对象标准的比较器_Java_Java Stream_Comparator - Fatal编程技术网

Java流排序-具有2个或更多对象标准的比较器

Java流排序-具有2个或更多对象标准的比较器,java,java-stream,comparator,Java,Java Stream,Comparator,问题:我正在尝试检查是否可以使用2个或更多条件对列表(数据类型对象的ArrayList)进行排序。请注意,我知道使用具有比较功能的比较器。我希望检查是否有一种方法可以使用2个或更多标准进行排序,而不必使用自定义数据类型,这样我就可以轻松地使用Comparator特性。对于1标准排序,以下代码起作用 在这种情况下,如果我执行以下操作,IntelliJ IDE会立即给出一个错误,对o.get(3)说“无法解析方法”get(int)” 在这个论坛示例中,我也提到了许多帖子- 代码(这适用于单一标准)

问题:我正在尝试检查是否可以使用2个或更多条件对列表(数据类型对象的ArrayList)进行排序。请注意,我知道使用具有比较功能的比较器。我希望检查是否有一种方法可以使用2个或更多标准进行排序,而不必使用自定义数据类型,这样我就可以轻松地使用Comparator特性。对于1标准排序,以下代码起作用

在这种情况下,如果我执行以下操作,IntelliJ IDE会立即给出一个错误,对o.get(3)说“无法解析方法”get(int)”

在这个论坛示例中,我也提到了许多帖子-

代码(这适用于单一标准)

List listOutput=new ArrayList();
.........
.........
listOutput=listOutput
.stream()
.sorted(Comparator.comparing(o->o.get(3.toString()))
.collect(Collectors.toList());
添加了(对象的详细信息)

(注)

字符串数据类型-交换、代理、段、coCode

LocalDate数据类型-tradeDate

LocalTime数据类型-tradeTime

双数据类型-sellPrice,buyPrice

List<Object> lineOutput = new ArrayList<>();
lineOutput.add(exchange);
lineOutput.add(broker);
lineOutput.add(segment);
lineOutput.add(tradeDate);  // Entry Date
lineOutput.add(tradeTime);   // Entry Time
lineOutput.add(coCode);
lineOutput.add(sellPrice - buyPrice);   // Profit / Loss 
listOutput.add(lineOutput); // Add line to Output
List lineOutput=new ArrayList();
lineOutput.add(交换);
添加(代理);
lineOutput.add(段);
lineOutput.add(贸易日期);//参赛日期
lineOutput.add(交易时间);//进场时间
lineOutput.add(coCode);
lineOutput.add(sellPrice-buyPrice);//盈亏
listOutput.add(lineOutput);//将行添加到输出

编译器似乎无法推断出正确的类型(我尝试了JavaC8和JavaC9,效果相同)。我能使其工作的唯一方法是通过强制转换直接指定类型:

list.stream()
    .sorted(
       Comparator.comparing((List<Object> o) -> o.get(3).toString())
                 .thenComparing((List<Object> x) ->  x.get(3).toString()));
list.stream()
.分类(
Comparator.comparing((列表o)->o.get(3.toString())
.然后比较((列表x)->x.get(3.toString());

我也有过几次这样的问题,尤其是在使用Comparator时。Eclipse和/或java编译器无法正确推断类型。正如霍尔格所指出的,这不是一个bug,而是按照指定的方式工作的:比较器中的类型不能仅仅通过
排序的
参数的预期类型来推断。您必须手动/显式键入以提供足够的信息进行编译:

List<List<Object>> listOutput = new ArrayList<>();
listOutput = listOutput.stream()
                       .sorted(Comparator.comparing((List<Object> o) -> o.get(3).toString())
                                         .thenComparing(o -> o.get(2).toString()))
                       .collect(Collectors.toList());
List listOutput=new ArrayList();
listOutput=listOutput.stream()
.sorted(Comparator.comparing((列表o)->o.get(3.toString())
.然后比较(o->o.get(2.toString())
.collect(Collectors.toList());

在随后的
中,比较
s,然后正确识别该类型。

如果错误为
则无法解决方法get
可能是因为您没有定义
o
的类型的
get
?如果我只按上面代码中所示的1个条件排序,则get方法工作正常。当我尝试扩展(即排序为2或更多)并进行比较时,IDE给出了错误。有趣的是,如果您将
对象
替换为实际的类,例如
用户
,这仍然失败-您需要显式地强制转换twiceThank you Malte,感谢您的帮助。Eugene的输入为我做了工作;确切地说,规范是如何定义它的;目标类型的类型推断无法通过链式方法调用进行。使用显式类型lambda表达式或精确方法引用(非泛型方法)可以提供足够的信息来推断第一个表达式的实际类型,然后,为第一个表达式提供精确类型,第一个表达式是后续调用的接收器,允许推断下一次调用的类型。@i命令确保使用Eugene的更新答案,该答案是类型安全的。@MalteHartwig,谢谢,我们已经合并了这些更改供您参考。我不知道IDE/编译器有这种需要强制转换的怪癖。不要使用类型强制转换,使用显式类型的lambdas:
Comparator.comparating((List o)->o.get(3.toString())。然后比较(o->…)
。请注意,第一个被输入的lambda如何为第二次(以及所有后续)调用提供类型,从而允许它使用隐式lambda…@Holger感谢您提供了这一见解。
list.stream()
    .sorted(
       Comparator.comparing((List<Object> o) -> o.get(3).toString())
                 .thenComparing((List<Object> x) ->  x.get(3).toString()));
List<List<Object>> listOutput = new ArrayList<>();
listOutput = listOutput.stream()
                       .sorted(Comparator.comparing((List<Object> o) -> o.get(3).toString())
                                         .thenComparing(o -> o.get(2).toString()))
                       .collect(Collectors.toList());