簡體   English   中英

如何在java中僅使用lambda按升序和降序對整數數組進行排序

[英]How to sort integer array in ascending and descending order using lambda only in java

int[] arr2 = new int[] {54, 432, 53, 21, 43};

我正在使用它來排序,但它給出了一個錯誤。

Arrays.sort(arr2, (a, b) -> a - b);

這也是一個錯誤。

arr2.sort((a, b) -> a - b);

您可以將Integer[]類型的輸入排序為:

Integer[] arr2 = new Integer[] {54,432,53,21,43};
Arrays.sort(arr2, Comparator.reverseOrder());

或者可能與原始類型:

int[] arr2 = new int[]{54, 432, 53, 21, 43};
int[] sortedArray = Arrays.stream(arr2)
        .boxed()
        .sorted(Comparator.reverseOrder()) // just use 'sorted()' for ascending order
        .mapToInt(Integer::intValue)
        .toArray();

或者進一步使用其中一個現有答案的技巧(請注意盡管應該謹慎使用邊界值):

int[] sortedArray = Arrays.stream(arr2)
        .map(i -> -i).sorted().map(i -> -i) // just use 'sorted()' for ascending order
// Edit - use map(i -> ~i).sorted().map(i -> ~i) to be safe from the issue with Integer.MIN_VALUE
        .toArray();

編輯 :對於就地升序排序,您只需執行:

int[] arr2 = new int[]{54, 432, 53, 21, 43};
Arrays.sort(arr2);

特定

int[] array = ... ;

要升序排序,只需這樣做

Arrays.sort(array);

這是一種排序降序的好方法:

Arrays.setAll(array, i -> ~array[i]);
Arrays.sort(array);
Arrays.setAll(array, i -> ~array[i]);

這比排序升序然后反轉陣列要慢一點; 它必須對數組進行額外的傳遞。 運行時主要是對任何大小的數組進行排序,因此它不太可能引人注意。

這通過在排序之前和之后對int值進行逐位補充來實現。 這提供了對每個可能的int值的排序的精確,無損的反轉。 要看到這一點,您必須了解Java int使用兩個補碼表示。 考慮一下int是否只有三位。 所有值都如下:

         100  101  110  111  000  001  010  011
          -4   -3   -2   -1   0    1    2    3
MIN_VALUE ^

按位補碼運算符~反轉每一位。 您可以通過檢查看到這反映了關於-1和0之間的軸心點的表格,因此-4變為3,-3變為2,等等。另外,另一個補碼將恢復原始值。 因此,對補充值的升序排序是對原始值的降序排序。

請注意,這與否定不同-這在這里做得不對。 它反映了零表,所以零否定為零,-1的否定是1,等等,這是不對稱的,因為MIN_VALUE的否定是MIN_VALUE。 因此,在嘗試執行降序排序時使用否定不起作用。

最后,裝箱和使用Comparator工作,但速度相當慢,並為(幾乎)每個int值分配一個單獨的對象。 我建議避免拳擊。

按升序排序:

  1.  int[] ascArr = Arrays.stream(arr2).boxed().sorted(Comparator.naturalOrder()) .mapToInt(Integer::intValue).toArray(); 
  2.  int[] ascArr = IntStream.of(arr2).boxed().sorted((a, b) -> Integer.compare(a, b)) .mapToInt(Integer::intValue).toArray(); 
  3. int[] ascArr = Arrays.stream(arr2).sorted().toArray();


按降序排序:

  1.  int[] descArr = Arrays.stream(arr2).boxed().sorted(Comparator.reverseOrder()) .mapToInt(Integer::intValue).toArray(); 
  2.  int[] descArr = IntStream.of(arr2).boxed().sorted((a, b) -> Integer.compare(b, a)) .mapToInt(Integer::intValue).toArray(); 

正如其他答案所示,有不同的方法可以使用流從未排序的int創建排序的int數組。 這些方法的缺點是需要裝箱/拆箱(以便可以使用Comparator<Integer> ),或者需要新的陣列來容納這些元素。

這是一種在沒有裝箱/拆箱的情況下就地排序的方法。 首先,按升序排列:

int[] arr2 = ...
Arrays.sort(arr2);

不幸的是,沒有辦法使用單行操作按降序排列就地。 您需要先升序,然后反轉數組:

int[] arr2 = ...
Arrays.sort(arr2);

int size = arr2.length;
for (int left = 0; left < size / 2; left++) {
    int right = size - i - 1;
    int temp = arr2[right];
    arr2[right] = arr2[left];
    arr2[left] = temp;
}

編輯:正如@Holger在評論中指出的那樣,上面的for循環可以改進如下:

for (int left = 0, right = arr2.length - 1; left < right; left++, right--) {
    int temp = arr2[right];
    arr2[right] = arr2[left];
    arr2[left] = temp;
}

另一種方法是按升序排序,然后將元素按相反順序放入新數組中:

int[] arr2 = ...
Arrays.sort(arr2);

int size = arr2.length;
int[] reversed = new int[size];
Arrays.setAll(reversed, i -> arr2[size - i - 1]);

這使用Arrays.setAll來完成任務。

public class lambdaTest {

    public static void main(String[] args) {
        int[] arr2 = new int[] {54,432,53,21,43};

        int[] sorted = IntStream.of(arr2)
                .boxed()
                .sorted(Comparator.reverseOrder())
                .mapToInt(i -> i)
                .toArray();
        System.out.println("In decending Order:");
        for(int ss : sorted)
        {
            System.out.print(ss+", ");
        }
        System.out.println();
        int[] reversed = IntStream.range(0, sorted.length)
                .map(i -> sorted[sorted.length-i-1])
                .toArray();
        System.out.println("In Ascending Order: ");

        for(int ss1 : reversed)
        {
            System.out.print(ss1+", ");
        }
    }

}

OUTPUT

按降序排列:

432,54,53,43,21,

在升序中:

21,43,53,54,432,

編輯:按自然順序排序要簡單得多(IntStream.of(arr2) .sorted() .toArray())

感謝Holger

如果您明確需要自定義比較器lambda,請嘗試以下方法:

    int[] arr2 = new int[] {54,432,53,21,43};
    int[] arr3 = IntStream.of(arr2).boxed().sorted((a, b) -> a - b).mapToInt(Integer::intValue).toArray();

暫無
暫無

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

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