java 如何有条件地反转最初使用比较器排序的流的顺序?

wqlqzqxt  于 2023-02-28  发布在  Java
关注(0)|答案(1)|浏览(131)

我有这样的代码,它选择并链接比较器:

class InputObject {  String inputName;  String ascending; }

Map<String, Comparator> comparatorsMap = .... // Used to dynamically pull comparators for use

List<InputObject> input = Arrays.asList(new InputObject("hello", true), new InputObject("goodbye", false));

Comparator<OutputObject> comparator = input.stream()
        .map(comparatorsMap::get)
        .reduce(Comparator::thenComparing)
        .orElse((a, b) -> 0);

List<OutputObject> sorted = dataCollection.stream().sorted( comparator ).collect( Collectors.toList() );

我想使用InputObject中的ascending字段作为条件来确定是否应该反转集合,但我不确定如何实现。请注意,每个输入对象都有自己的ascending字段,因此这些必须是中间操作。
例如:
未排序(输入流为[ {"byName", false}, {"byID", true} ]):

OutputObject=("Mike", 5)
OutputObject=("Bob", 4)
OutputObject=("Mike", 1)

第一次排序后(按名称):

OutputObject=("Bob", 4)
OutputObject=("Mike", 5)
OutputObject=("Mike", 1)

然后反转(从ascending == false开始)

OutputObject=("Mike", 5)
OutputObject=("Mike", 1)
OutputObject=("Bob", 4)

然后在应用第二次排序(如果相同,则按ID和ascending == true)之后

OutputObject=("Mike", 1)
OutputObject=("Mike", 5)
OutputObject=("Bob", 4)

我考虑过在map lambda中保存一个布尔字段,然后在另一个lambda中利用它,但我不确定如何有条件地应用反转流/集合的操作。

k4emjkb1

k4emjkb11#

我觉得你在找这样的东西:

Comparator<OutputObject> comparator = input.stream()
        .map(in -> {
          Comparator<OutputObject> c = comparatorsMap.get(in.inputName);
          return in.ascending ? c : c.reversed();
        })
        .reduce(Comparator::thenComparing)
        .orElse((a, b) -> 0);

这将根据ascending标志有条件地反转比较器,使其与comparatorsMap相反。
我考虑过在map lambda中保存一个布尔字段,然后在另一个lambda中利用它
你可以这样做:

input.stream()
    .map(in -> new AbstractMap.SimpleEntry<>(comparatorsMap.get(in.inputName), in.ascending))
    .map(e -> e.getValue() ? e.getKey() : e.getKey().reversed())
    ...

但我觉得这很难理解。

相关问题