簡體   English   中英

如何在java 8中將字符串排序為帶有lambdas的int

[英]How to sort strings as ints with lambdas in java 8

我有一個對象列表,每個對象都有一個返回字符串的方法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)來解析數字。 它已在Java 9中棄用 如果你堅持裝箱值(在這種情況下是浪費Integer.parseInt​(String s) ,請使用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);

除此之外,看起來很好,即使它失敗了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM