【问题标题】:Java 8 Lambda ExpressionsJava 8 Lambda 表达式
【发布时间】:2017-11-16 16:32:47
【问题描述】:

我一直坚持使用一个 lambda 表达式和使用 Comparator.comparing(...).thenComparing(...) 方法的 Comparator 类来总结两种对流进行排序的方式。

我的两种方法都有效,但是当我将它们放在一起时,根本没有任何效果。

如果您想尝试验证练习,请点击以下链接:

http://codecheck.it/codecheck/files?repo=heigvdcs1&problem=poo3e

这是你必须做的:

对于流中的每个单词,确定“元音”,即元音的数量 - 辅音的数量。生成与元音值配对的元音最高的n 单词。首先按元音排序,然后按字符串排序。完成这个程序。 这一次,您可以使用一个隐藏的静态方法 long Words.vowels(String w),它可以生成 w 中元音的数量,包括重复。

现在我已经做到了:

import java.util.*;
import java.util.stream.*;

public class Streams
{
   List<Pair<String, Long>> wordsWithManyVowels(Stream<String> words, int n)
   {
      return words
         .map( w -> Pair.of( w , ( Words.vowels(w) - ( w.length() - Words.vowels(w)))))
         .sorted(Comparator.comparingLong(f1 -> -f1.second())
         //This part is working without the first comparing
         //.thenComparing(f2 -> f2.first().length()))
         .limit(n)
         .collect(Collectors.toList());
   }
}

Pair 类:

import java.util.Objects;

public class Pair<T, S> 
{
   private T first;
   private S second;

   public Pair(T firstElement, S secondElement)
   {
      first = firstElement;
      second = secondElement;
   }

   /*
      Use Pair.of(x, y) instead of new Pair<...,...>(x, y)
      so you get the type inferred
   */

   public static <T, S> Pair<T, S> of(T firstElement, S secondElement)
   {
      return new Pair<T, S>(firstElement, secondElement);
   }

   public T first() { return first; }
   public S second() { return second; }

   public String toString() { return "(" + first + "," + second + ")"; }

   public boolean equals(Object otherObject)
   {
      if (this == otherObject) 
         return true;
      if (otherObject == null || !(otherObject instanceof Pair)) 
         return false;
      @SuppressWarnings("unchecked") Pair<T, S> other = (Pair<T, S>) otherObject;
      return Objects.equals(first, other.first) &&
         Objects.equals(second, other.second);
   }
}

【问题讨论】:

  • “什么都没有工作”是什么意思?发生什么了?异常、编译错误、错误的排序顺序?
  • 您的 f2 -&gt; f2.first().length()) 函数是一个 int 提取器,因此该方法不应该是:thenComparingInt 吗?
  • @MalteHartwig 这意味着该方法无法协同工作。虽然是分开工作
  • 附注:不要使用否定来颠倒顺序。在Long.MIN_VALUE的情况下,由于溢出而不起作用,同样适用于其他整数类型的最小值。很容易说这对于特定属性永远不会发生,但是一旦这个假设不再成立并且你不记得你在代码中的某个地方做出了这个假设,这将花费你很多时间。你可以使用Comparator.comparingLong(Pair&lt;String, Long&gt;::second) .reversed() .thenComparingInt(p -&gt; p.first().length())

标签: java lambda java-8 java-stream comparator


【解决方案1】:

解决方案 1

将比较方法提取为static 的工作方式如下

public class Streams {
    List<Pair<String, Long>> wordsWithManyVowels(Stream<String> words, int n) {
        return words
            .map(w -> Pair.of(w, (Words.vowels(w) - (w.length() - Words.vowels(w)))))
            .sorted(Comparator.comparingLong(Streams::vowelness).thenComparingInt(Streams::length))
            .limit(n)
            .collect(Collectors.toList());
    }

    static int length(Pair<String, Long> p) {
        return p.first().length();
    }

    static long vowelness(Pair<String, Long> p) {
        return -p.second();
    }
}

解决方案 2

使用此 Comparator 实现而不使用 static 方法

Comparator
    .comparingLong((Pair<String, Long> p) -> -p.second())
    .thenComparingInt((Pair<String, Long> p) -> p.first().length())

注意:看看thenComparingInt在两个解决方案中复合比较器的末尾是如何使用的。

解决方案 3

源代码的问题是静态Comparator 方法需要有关处理链中元素类型的信息。默认使用Object 类型。因此,可以这样指定(比解决方案 2 更简单):

Comparator.<Pair<String, Long>>comparingLong(p -> -p.second()).thenComparing(p -> p.first().length())

【讨论】:

  • Andriy,你能解释一下 Thomas 的代码中到底有什么错误吗?
  • @MalteHartwig 请参阅解决方案 3:这是编译错误,因为编译器无法理解所需的 Pair 类型链式静态方法。
  • @AndriyKryvtsun 谢谢你的帮助,我现在理解得更好了。但是您的解决方案正在工作,尽管它们按长度对字符串进行排序,我需要它们按字母顺序排序。那就是为什么我没有使用 thenCampingInt()。但是谢谢你,我会从那时起找到方法
  • @ThomasL 如果您需要按字母顺序比较字符串,只需使用此子句.thenComparing(Pair::first)。所以整个比较器看起来像这样Comparator.&lt;Pair&lt;String, Long&gt;&gt;comparingLong(Pair::second).reversed().thenComparing(Pair::first)
  • @AndriyKryvtsun 谢谢我这样做:Comparator.comparingLong((Pair&lt;String, Long&gt; p) -&gt; -p.second()) .thenComparing((Pair&lt;String, Long&gt; p) -&gt; p.first())
猜你喜欢
  • 1970-01-01
  • 2015-06-01
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
相关资源
最近更新 更多