杰瑞科技汇

Java数组排序如何实现自定义比较?

Of course! Sorting arrays is a fundamental task in Java. The language provides several ways to do it, each suited for different scenarios.

Java数组排序如何实现自定义比较?-图1
(图片来源网络,侵删)

Here's a comprehensive guide to sorting arrays in Java, from the simplest built-in methods to more advanced custom sorting.

The Simple Way: Arrays.sort() for Primitive Types

For arrays of primitive types (int, double, char, etc.), Java provides a simple, one-line solution using the java.util.Arrays utility class. This method uses a highly optimized, dual-pivot Quicksort algorithm, which is very fast for most real-world data.

Example: Sorting an int[] array

import java.util.Arrays;
public class PrimitiveSort {
    public static void main(String[] args) {
        int[] numbers = {5, 1, 9, 3, 7, 2, 8, 4, 6};
        System.out.println("Array before sorting: " + Arrays.toString(numbers));
        // Sort the array in ascending order
        Arrays.sort(numbers);
        System.out.println("Array after sorting:  " + Arrays.toString(numbers));
    }
}

Output:

Array before sorting: [5, 1, 9, 3, 7, 2, 8, 4, 6]
Array after sorting:  [1, 2, 3, 4, 5, 6, 7, 8, 9]

Key Points:

Java数组排序如何实现自定义比较?-图2
(图片来源网络,侵删)
  • In-place Sort: Arrays.sort() modifies the original array. It does not return a new one.
  • Ascending Order Only: This method sorts arrays in natural ascending order only.
  • For all primitives: This works for int, long, double, float, char, and short.

Sorting Object Arrays (e.g., String[], Integer[])

When you sort an array of objects, you need a way to define what "less than" or "greater than" means for those objects. Java uses the Comparable interface for this.

a) Using Arrays.sort() with Comparable Objects

Many standard Java classes, like String and Integer, already implement the Comparable interface. This means you can sort them directly.

import java.util.Arrays;
public class ObjectSortComparable {
    public static void main(String[] args) {
        String[] names = {"Charlie", "Alice", "David", "Bob"};
        System.out.println("Array before sorting: " + Arrays.toString(names));
        // String implements Comparable, so this works
        Arrays.sort(names);
        System.out.println("Array after sorting:  " + Arrays.toString(names));
    }
}

Output:

Array before sorting: [Charlie, Alice, David, Bob]
Array after sorting:  [Alice, Bob, Charlie, David]

What if you want to sort in descending order? The basic Arrays.sort() doesn't support this. You need a different approach.

b) Using Arrays.sort() with a Comparator

A Comparator is an object that allows you to define a custom sorting order without changing the class's original compareTo method. This is extremely flexible.

The Arrays.sort() method has an overloaded version that takes a Comparator.

Example 1: Sorting Strings in Descending Order

import java.util.Arrays;
import java.util.Comparator;
public class SortWithComparator {
    public static void main(String[] args) {
        String[] names = {"Charlie", "Alice", "David", "Bob"};
        System.out.println("Array before sorting: " + Arrays.toString(names));
        // Sort the array using a custom Comparator for descending order
        Arrays.sort(names, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                // For descending order, reverse the natural comparison
                return s2.compareTo(s1);
            }
        });
        // A more modern way using a lambda expression (Java 8+)
        // Arrays.sort(names, (s1, s2) -> s2.compareTo(s1));
        System.out.println("Array after sorting (descending): " + Arrays.toString(names));
    }
}

Output:

Array before sorting: [Charlie, Alice, David, Bob]
Array after sorting (descending): [David, Charlie, Bob, Alice]

Example 2: Sorting a Custom Object Array

Let's say you have a Product class and you want to sort an array of Product objects by their price.

import java.util.Arrays;
import java.util.Comparator;
// A custom class that does NOT implement Comparable
class Product {
    String name;
    double price;
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    @Override
    public String toString() {
        return name + " ($" + price + ")";
    }
}
public class SortCustomObject {
    public static void main(String[] args) {
        Product[] products = {
            new Product("Laptop", 1200.50),
            new Product("Mouse", 25.00),
            new Product("Keyboard", 75.99)
        };
        System.out.println("Before sorting: " + Arrays.toString(products));
        // Sort by price in ascending order
        Arrays.sort(products, new Comparator<Product>() {
            @Override
            public int compare(Product p1, Product p2) {
                // Compare doubles
                return Double.compare(p1.price, p2.price);
            }
        });
        // Using a lambda (Java 8+)
        // Arrays.sort(products, (p1, p2) -> Double.compare(p1.price, p2.price));
        System.out.println("After sorting by price (ascending): " + Arrays.toString(products));
    }
}

Output:

Before sorting: [Laptop ($1200.5), Mouse ($25.0), Keyboard ($75.99)]
After sorting by price (ascending): [Mouse ($25.0), Keyboard ($75.99), Laptop ($1200.5)]

Advanced Sorting: Parallel Sort

For very large arrays, you can leverage multi-core processors to speed up sorting. Java provides Arrays.parallelSort(), which is a parallel version of sort().

It works by dividing the array into smaller chunks, sorting them in parallel on different threads, and then merging the results.

import java.util.Arrays;
public class ParallelSortExample {
    public static void main(String[] args) {
        // Create a large array
        int[] largeArray = new int[10_000_000];
        for (int i = 0; i < largeArray.length; i++) {
            largeArray[i] = (int) (Math.random() * largeArray.length);
        }
        // Use parallelSort for large datasets
        // It automatically chooses the best algorithm (often a parallel merge sort)
        Arrays.parallelSort(largeArray);
        // For smaller arrays, the overhead of parallelism might not be worth it.
        // Arrays.sort() is often faster.
        System.out.println("First 10 elements after parallelSort: " + 
            Arrays.toString(Arrays.copyOfRange(largeArray, 0, 10)));
    }
}

Key Points:

  • Use Arrays.parallelSort() for large arrays (typically tens of thousands of elements or more).
  • It works for both primitive and object arrays.
  • It throws IllegalArgumentException if the comparator is null and an element in the array does not implement Comparable.

Summary Table

Method What it Sorts Order Algorithm Key Feature
Arrays.sort(primitive[]) Primitives (int, double, etc.) Ascending only Dual-Pivot Quicksort Fast, simple, in-place.
Arrays.sort(Object[]) Objects (String, Integer, etc.) Ascending (natural order) TimSort Requires objects to implement Comparable.
Arrays.sort(Object[], Comparator) Any Object Custom TimSort Most flexible. Allows any custom order.
Arrays.parallelSort(...) Primitives or Objects Ascending or Custom (with Comparator) Parallel Merge Sort Best for very large arrays to utilize multiple CPU cores.

Key Concepts to Remember

  1. In-place: Most Arrays.sort() methods modify the original array.
  2. Comparable vs. Comparator:
    • Comparable defines a natural ordering for a class (e.g., String's alphabetical order). It's implemented inside the class itself.
    • Comparator defines an external ordering. You can create multiple Comparators for the same class to sort in different ways (e.g., by name, by price, by date). It's more flexible.
  3. Lambda Expressions (Java 8+): For creating Comparators, lambda expressions make the code much more concise and readable.
    • Instead of new Comparator<T>() { ... }, you can write (t1, t2) -> ....
    • Example: Arrays.sort(products, (p1, p2) -> p1.name.compareTo(p2.name));
分享:
扫描分享到社交APP
上一篇
下一篇