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

问题描述 投票:3回答:3

我有一个对象列表,每个对象都有一个返回字符串的方法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. 如果按整数顺序排序失败,即它是否会按字典顺序排列列表,我不确定这是否有效。
java sorting lambda
3个回答
4
投票

不要使用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));

2
投票

为了使您的代码有效,只需返回“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。


1
投票

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

return seq1.compareTo(seq2);

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

© www.soinside.com 2019 - 2024. All rights reserved.