跳转到内容

Java Stream排序

来自代码酷

Java Stream排序[编辑 | 编辑源代码]

Java Stream排序是Java Stream API中的一个核心操作,允许开发者按照特定规则对数据流中的元素进行排序。Stream排序操作既支持自然排序(如数字、字符串的升序或降序),也支持自定义排序(通过比较器)。本文将详细介绍Stream排序的使用方法、常见场景及实际案例。

概述[编辑 | 编辑源代码]

Java Stream API(从Java 8引入)提供了一种声明式处理集合数据的方式。排序(`sorted()`)是Stream的中间操作之一,它可以对流中的元素重新排列。排序操作分为两种:

  • 自然排序:使用元素的自然顺序(如数字从小到大、字符串按字典序)。
  • 自定义排序:通过传入`Comparator`来定义排序规则。

排序操作不会修改原始数据源,而是返回一个新的排序后的Stream。

基本语法[编辑 | 编辑源代码]

Stream排序的基本语法如下:

// 自然排序
Stream<T> sorted();

// 自定义排序
Stream<T> sorted(Comparator<? super T> comparator);

自然排序示例[编辑 | 编辑源代码]

以下示例展示如何对一个整数列表进行升序排序:

import java.util.List;
import java.util.stream.Collectors;

public class StreamSortingExample {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(5, 3, 8, 1, 2);

        List<Integer> sortedNumbers = numbers.stream()
            .sorted()
            .collect(Collectors.toList());

        System.out.println("原始列表: " + numbers);
        System.out.println("排序后列表: " + sortedNumbers);
    }
}

输出:

原始列表: [5, 3, 8, 1, 2]
排序后列表: [1, 2, 3, 5, 8]

自定义排序示例[编辑 | 编辑源代码]

通过`Comparator`可以定义更复杂的排序规则。以下示例按字符串长度排序:

import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;

public class CustomSortingExample {
    public static void main(String[] args) {
        List<String> words = List.of("apple", "banana", "cherry", "date");

        List<String> sortedByLength = words.stream()
            .sorted(Comparator.comparingInt(String::length))
            .collect(Collectors.toList());

        System.out.println("原始列表: " + words);
        System.out.println("按长度排序: " + sortedByLength);
    }
}

输出:

原始列表: [apple, banana, cherry, date]
按长度排序: [date, apple, banana, cherry]

多条件排序[编辑 | 编辑源代码]

在某些情况下,需要按多个条件排序。例如,先按字符串长度排序,长度相同的再按字母顺序排序:

import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;

public class MultiConditionSorting {
    public static void main(String[] args) {
        List<String> words = List.of("apple", "banana", "cherry", "date", "fig");

        List<String> sortedWords = words.stream()
            .sorted(Comparator.comparingInt(String::length)
                .thenComparing(Comparator.naturalOrder()))
            .collect(Collectors.toList());

        System.out.println("多条件排序结果: " + sortedWords);
    }
}

输出:

多条件排序结果: [date, fig, apple, banana, cherry]

降序排序[编辑 | 编辑源代码]

通过`Comparator.reverseOrder()`或`reversed()`方法可以实现降序排序:

import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;

public class DescendingSortExample {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(5, 3, 8, 1, 2);

        List<Integer> descendingNumbers = numbers.stream()
            .sorted(Comparator.reverseOrder())
            .collect(Collectors.toList());

        System.out.println("降序排序: " + descendingNumbers);
    }
}

输出:

降序排序: [8, 5, 3, 2, 1]

实际应用案例[编辑 | 编辑源代码]

案例1:学生成绩排序[编辑 | 编辑源代码]

假设有一个学生列表,需要按成绩从高到低排序:

import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;

class Student {
    String name;
    int score;

    Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return name + " (" + score + ")";
    }
}

public class StudentSorting {
    public static void main(String[] args) {
        List<Student> students = List.of(
            new Student("Alice", 85),
            new Student("Bob", 72),
            new Student("Charlie", 90)
        );

        List<Student> sortedStudents = students.stream()
            .sorted(Comparator.comparingInt(Student::getScore).reversed())
            .collect(Collectors.toList());

        System.out.println("按成绩降序排序:");
        sortedStudents.forEach(System.out::println);
    }
}

输出:

按成绩降序排序:
Charlie (90)
Alice (85)
Bob (72)

案例2:电商商品排序[编辑 | 编辑源代码]

在电商平台中,商品可能按价格、销量或评分排序:

import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;

class Product {
    String name;
    double price;
    int sales;

    Product(String name, double price, int sales) {
        this.name = name;
        this.price = price;
        this.sales = sales;
    }
}

public class ProductSorting {
    public static void main(String[] args) {
        List<Product> products = List.of(
            new Product("Laptop", 999.99, 150),
            new Product("Phone", 699.99, 300),
            new Product("Tablet", 399.99, 200)
        );

        // 按价格升序排序
        List<Product> byPrice = products.stream()
            .sorted(Comparator.comparingDouble(Product::getPrice))
            .collect(Collectors.toList());

        // 按销量降序排序
        List<Product> bySales = products.stream()
            .sorted(Comparator.comparingInt(Product::getSales).reversed())
            .collect(Collectors.toList());

        System.out.println("按价格排序:");
        byPrice.forEach(p -> System.out.println(p.name + " - $" + p.price));

        System.out.println("\n按销量排序:");
        bySales.forEach(p -> System.out.println(p.name + " - " + p.sales + " sold"));
    }
}

输出:

按价格排序:
Tablet - $399.99
Phone - $699.99
Laptop - $999.99

按销量排序:
Phone - 300 sold
Tablet - 200 sold
Laptop - 150 sold

性能考虑[编辑 | 编辑源代码]

Stream排序是一个有状态的操作,可能影响性能:

  • 对于大型数据集,排序可能消耗较多内存和时间。
  • 并行流(`parallelStream()`)可能提高排序速度,但需注意线程安全问题。

总结[编辑 | 编辑源代码]

Java Stream排序提供了一种灵活且强大的方式对数据进行排序:

  • 使用`sorted()`进行自然排序。
  • 通过`Comparator`实现自定义或多条件排序。
  • 适用于各种实际场景,如学生成绩、商品排序等。

掌握Stream排序能显著提升代码的可读性和功能性,是Java开发者必备技能之一。