如何在java 8中将字符串排序为带有lambdas的int

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在java 8中将字符串排序为带有lambdas的int相关的知识,希望对你有一定的参考价值。

我有一个对象列表,每个对象都有一个返回字符串的方法getNumOrder。列表中的对象按字典顺序排序。大多数情况下,列表中的所有对象都具有返回整数的getNumOrder(但并非总是如此)。

如果列表中的所有元素都有整数的NumOrders,我想使用整数排序顺序对它们进行排序。否则,它们将按字典顺序排列。

我使用Java 8 Lambdas尝试过这个

try {
    results.sort((r1,r2)-> {
        Integer seq1= new Integer(r1.getNumOrder());
        Integer seq2= new Integer(r2.getNumOrder());
        seq1.compareTo(seq2);
    });
}
catch (Exception e) {
    // Do nothing: Defaults to lexicographical order.
}

有两个问题:

  1. 因为我不太了解Lambda表达式,所以语法不正确
  2. 如果按整数顺序排序失败,即它是否会按字典顺序排列列表,我不确定这是否有效。
答案

不要使用new Integer(String)来解析数字。它一直是deprecated in Java 9。如果你坚持拳击价值(在这种情况下是浪费),请使用Integer.parseInt​(String s)Integer.valueOf​(String s)

你追求的lambda将是:

results.sort((r1,r2) -> Integer.compare(Integer.parseInt(r1.getNumOrder()),
                                        Integer.parseInt(r2.getNumOrder())));

如果排序失败,这会使results保持不变,因为sort()方法将列表元素复制到数组,对数组进行排序,然后将元素复制回来。

如果您希望将中间值存储在变量中,例如所以你可以在调试时看到它们,你将使用一个lambda块,它需要一个return语句。这就是你的代码中缺少的东西。

results.sort((r1,r2) -> {
        int i1 = Integer.parseInt(r1.getNumOrder());
        int i2 = Integer.parseInt(r2.getNumOrder());
        return Integer.compare(i1, i2);
});

答案的下面部分是基于误解输入是字符串列表,但它不是,因此它不适用于问题,但我将其留给可能有类似问题的其他人,其中输入是字符串列表。

但这不是好表现。如果字符串没有需要保留的前导零,则最好解析为int,对int值进行排序,然后格式化回字符串。

使用流(Java 8+):

results = results.stream()
                 .mapToInt(Integer::parseInt)
                 .sorted()
                 .mapToObj(Integer::toString)
                 .collect(Collectors.toList());

或者这个非流版本(Java 1.2+):

int[] arr = new int[results.size()];
int i = 0;
for (String s : results)
    arr[i++] = Integer.parseInt(s);
Arrays.sort(arr);
results.clear();
for (int v : arr)
    results.add(Integer.toString(v));
另一答案

为了使您的代码有效,只需返回“seq1.compareTo(seq2);”像这样:

try {
      results.sort((r1,r2)-> {
                        Integer seq1= new Integer(r1.getNumOrder());
                        Integer seq2= new Integer(r2.getNumOrder());
                        return seq1.compareTo(seq2);
                });
}
catch (Exception e) {
    // Do nothing: Defaults to lexicographical order.
}

正如@Andreas在评论中所指出的那样,不应该这样做(使用装箱并使用构造函数将String解析为整数),有一种更清洁且“不那么浪费”的方法来实现它。这是代码:

try {
       results.sort((r1,r2)-> 
                     Integer.compare(Integer.parseInt(r1.getNumOrder()),
                                     Integer.parseInt(r2.getNumOrder()))
                );
}
catch (Exception e) {
    // Do nothing: Defaults to lexicographical order.
}

请记住,当你使用括号时,你只需要(显式地)在lambda中返回一个值,因为它的处理就像一个方法 - 在“sort”的情况下 - 应该返回一个Integer。

另一答案

你刚忘了你的lambda中的“回归”:

return seq1.compareTo(seq2);

除此之外,看起来很好,即使它失败了

以上是关于如何在java 8中将字符串排序为带有lambdas的int的主要内容,如果未能解决你的问题,请参考以下文章

如何在基于 lambda 演算的系统中将 beta 归约还原为命名函数?

如何使用 Java 8 lambda 从流中获取一系列项目?

Java 8:带有 where 条件的 Lambda 表达式

java: 带有 lambda 表达式的 Arrays.sort()

java 8中列表对象多条件排序

Java 8:带有可变参数的 Lambda