【问题标题】:Sorting with stream.sorted() in Java在 Java 中使用 stream.sorted() 进行排序
【发布时间】:2018-09-22 22:14:00
【问题描述】:

我有例如 sg-1、sg-5、sg-13、sg-6 等元素的列表,我需要按数字对它们进行排序。 我的代码部分是:

}).map(c -> {
                System.out.println(c);
                return c;
            }).distinct()
            .sorted((c1, c2) -> c1.substring(c1.indexOf("-"), c1.length())
                    .compareTo(c2.substring(c2.indexOf("-"), c2.length())))
            .collect(Collectors.toList());

系统输出打印 SG-1 SG-1 SG-1 SG-9 SG-1 SG-4 SG-15 SG-1 SG-1 SG-1 SG-1

但最后我得到 [sg-1, sg-15, sg-4, sg-9] 但是它必须是 [sg-1, sg-4, sg-9, sg-15] 如何对它们进行排序,请帮助我的:)

【问题讨论】:

  • c1.substring(c1.indexOf("-"), c1.length()) 返回一个带有破折号(-)的值,该值被视为负数。例如,您的代码将返回 -1, -5, -13 而不是 1,5,13,您可以使用 c1.substring(c1.indexOf("-") + 1, c1.length()) 跳过破折号 (-)。我不明白你为什么要使用地图。
  • 所以,是的,你是对的,但是我尝试使用 .sorted((c1, c2) -> c1.substring(c1.indexOf("-") + 1, c1.length ()) .compareTo(c2.substring(c2.indexOf("-") + 1, c2.length()))) .collect(Collectors.toList());但它不起作用。可能是“comparedTo”无法正确排序数字,如果它们是字符串而不是整数或整数?

标签: java sorting java-stream comparator


【解决方案1】:

您做错的第一件事是您按字典顺序比较字符串,而不是您可能期望的整数。

其次,即使您将c1.substring(c1.indexOf("-"), c1.length()) 转换为整数然后进行比较,您仍然会得到不正确的结果。

这是为什么呢?

这是因为c1.substring(c1.indexOf("-"), c1.length()),子字符串的第一个参数是inclusive,这意味着你总是会提取负数。

解决方案:

  1. 您实际上需要比较整数而不是字符串。
  2. substring 的第一个参数实际上应该是c1.indexOf("-") + 1 以在“-”之后开始。

List<String> result = list.stream()
                .distinct()
                .sorted(Comparator.comparingInt(s -> 
                    Integer.parseInt(s.substring(s.indexOf("-") + 1, s.length()))))
                .collect(Collectors.toList());

顺便说一句,不要使用map 来执行调试工作,而是使用peek

List<String> result = list.stream()
                 .peek(System.out::println)
                 .distinct()
                 .sorted(Comparator.comparingInt(s -> 
                     Integer.parseInt(s.substring(s.indexOf("-") + 1, s.length()))))
                 .collect(Collectors.toList());

【讨论】:

  • 请注意,substring 的单参数版本已经暗示 length() 作为第二个参数。此外,如果您可以排除前导零,则可以在仅预先进行长度比较时继续进行字符串比较:Comparator.comparingInt((String s) -&gt; s.length()-s.indexOf("-")) .thenComparing(s -&gt; s.substring(s.indexOf("-")+1))
  • @Holger 好声音!在撰写本文时完全忘记了超载,也感谢以下建议。一如既往的感激。
【解决方案2】:

请尝试一下

List<String> result = list.stream().distinct().sorted((a1,a2)->{
        return Integer.compare(Integer.parseInt(a1.split("-")[1]), Integer.parseInt(a2.split("-")[1]));
    }).collect(Collectors.toList());

【讨论】:

  • 它有效,但你能解释一下,这些 [1] 是什么意思?为什么我的代码没有得到排序结果?
  • 这段代码根据破折号 (-) 拆分各个字符串。然后它采用字符串的第二部分,即末尾的数字。对于“sg-1”,将其拆分为“sg”和“1”。它获取数字并转换为整数并进行比较。希望这会有所帮助。
  • 避免使用原始类型。使用泛型要好得多
  • 另外,您当前的方法效率低下,因为每次调用sorted 的函数时都会创建两个数组对象,这可以避免。
猜你喜欢
  • 2017-03-23
  • 2012-07-15
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 2013-08-12
  • 2014-07-05
  • 2017-06-28
  • 2016-06-10
相关资源
最近更新 更多