【问题标题】:Sort List<Integer> using Lambda expression使用 Lambda 表达式对 List<Integer> 进行排序
【发布时间】:2018-11-07 18:21:34
【问题描述】:

如何使用 Lambda 表达式对其进行排序? 我想对前 7 个数字进行排序并排除最后一个数字。我看到可以使用 IntStream.concat 但我需要使用 Lambda 表达式进行排序。

     Random random = new Random();
        List <Integer> lucky = random.ints (1, 64)
                                     .distinct()
                                     .limit(8)
                                     .boxed()
                                     .sorted()
                                     .collect(Collectors.toList());

【问题讨论】:

  • 根据什么排序?
  • 为什么要坚持使用 lambda?
  • 您需要生成随机整数并在一个表达式中对它们进行排序还是可以在两个表达式中完成?
  • @NicholasK 按升序排序。
  • @Sweeper 最好是 lambda,因为我们需要实现 lambda 表达式

标签: java sorting lambda


【解决方案1】:

“使用 lambda 表达式”的要求很奇怪。我只需将 .limit 调用替换为

即可满足此要求
.limit(((IntSupplier)() -> 8).getAsInt())

看!我在那里使用了一个lambda! () -&gt; 8。然后你可以继续用concat 解决问题,就像你说的那样。

显然,这不是你的意思。

如果你想在 sort 方法中加入一个 lambda 来对前 7 个整数进行排序,然后总是将第 8 个留在最后,你可以这样做:

Random random = new Random();
List<Integer> unsorted = random.ints(1, 64)
        .distinct()
        .limit(8)
        .boxed()
        .collect(Collectors.toList());

// here you need to get the last element that you don't want to sort
int last = unsorted.get(unsorted.size() - 1);
// here is the lambda
List<Integer> sorted = unsorted.stream().sorted((x, y) -> {
    if (Integer.compare(x, y) == 0) {
        return 0;
    }
    // if any one of the arguments is the last one...
    if (last == x) {
        return 1;
    }
    if (last == y) {
        return -1;
    }
    return Integer.compare(x, y);
}).collect(Collectors.toList());
// you can also use "List.sort" with the same lambda

请注意,我个人觉得这个sorted 方法调用非常不可读。乍一看,我看不出您正在尝试对除最后一个以外的所有内容进行排序。在可读性方面,使用concat会更好。

【讨论】:

  • 令人惊讶的是,我不认为Comparator 的这种实现违反了一般合同!我以为这会违反合同。
  • 我打算使用 Collections.sort(lucky.sublist(0,6)) 因为我没有看到使用 Lambda 进行排序的意义,除非我误解了我的教授所说的意思“我不希望你实现一些排序方法来对它们进行排序。你正在从事函数式编程;Lambda 可以帮助你实现这个目标。”
  • @KevinChee 好吧,你并没有真正编写排序方法。 lambda 只比较两个整数。
【解决方案2】:

您可以使用 lambda 作为Collections.sort() 的第二个参数,提供子列表作为第一个参数:

Collections.sort(lucky.subList(0, lucky.size()-1), 
                 (i1, i2) -> i1.compareTo(i2));

这将等价于Collections.sort(lucky.subList(0, lucky.size()-1)),因此您在这里并不需要这个 lambda 表达式。

另一种方法(不是一种有效的方法)是使用Stream.concat()

List<Integer> sorted = Stream.concat(
        lucky.stream()
             .filter(elem -> !elem.equals(lucky.get(lucky.size() - 1))).sorted(),
        Stream.of(lucky.get(lucky.size() - 1)))
                       .collect(Collectors.toList());

请注意,我是根据值而不是索引过滤第一个流中的项目,因为lucky 列表中的项目是不同的。这可以基于索引来完成,尽管这会使排序的性能更差。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    相关资源
    最近更新 更多