当前位置:首页 > 技术 > 正文内容

Java Stream API 详解

访客 技术 2026年7月19日 1

一、Stream API 概述

在实际开发中,我们经常会遇到这样的场景:有一个商品列表,需要筛选出价格低于某个值的商品,按价格排序后获取商品名称。

这种需求在以往通常需要通过多层循环和条件判断来实现,代码冗长且难以维护。Java 8 引入的 Stream API 提供了一种优雅的解决方案,它允许我们以声明式的方式处理数据集合。

让我们先定义一个商品类:

``` package com.example.model;

public class Product {

private final String productName;
private final boolean inStock;
private final int price;
private final Category category;

public Product(String productName, boolean inStock, int price, Category category) {
    this.productName = productName;
    this.inStock = inStock;
    this.price = price;
    this.category = category;
}

public String getProductName() {
    return productName;
}

public boolean isInStock() {
    return inStock;
}

public int getPrice() {
    return price;
}

public Category getCategory() {
    return category;
}

public enum Category {ELECTRONICS, CLOTHING, FOOD, BOOKS}

@Override
public String toString() {
    return "Product{" +
            "productName='" + productName + '\'' +
            ", inStock=" + inStock +
            ", price=" + price +
            ", category=" + category +
            '}';
}

}


View Code```
package com.example.stream;

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

public class StreamDemo {

    public static void main(String[] args) {
        List<Product> productList = Arrays.asList(
                new Product("Laptop", false, 800, Product.Category.ELECTRONICS),
                new Product("Smartphone", false, 700, Product.Category.ELECTRONICS),
                new Product("T-Shirt", true, 400, Product.Category.CLOTHING),
                new Product("Jeans", true, 530, Product.Category.CLOTHING),
                new Product("Apple", true, 350, Product.Category.FOOD),
                new Product("Banana", true, 120, Product.Category.FOOD),
                new Product("Novel", true, 550, Product.Category.BOOKS),
                new Product("Headphones", false, 300, Product.Category.ELECTRONICS),
                new Product("Textbook", false, 450, Product.Category.BOOKS));

        List<String> affordableProducts = getAffordableProducts(productList);
        System.out.println(affordableProducts);

        List<String> affordableProducts2 = getAffordableProductsWithStream(productList);
        System.out.println(affordableProducts2);
    }

    /**
     * 使用传统方式实现
     * 筛选价格低于400的商品,按价格排序,返回商品名称列表
     */
    private static List<String> getAffordableProducts(List<Product> productList) {
        List<Product> filteredProducts = new ArrayList<>();
        
        for (Product product : productList) {
            if (product.getPrice() < 400) {
                filteredProducts.add(product);
            }
        }
        
        filteredProducts.sort(Comparator.comparingInt(Product::getPrice));

        List<String> result = new ArrayList<>();
        for (Product product : filteredProducts) {
            result.add(product.getProductName());
        }
        return result;
    }

    /**
     * 使用 Stream API 实现
     */
    private static List<String> getAffordableProductsWithStream(List<Product> productList) {
        return productList.stream()
                .filter(product -> product.getPrice() < 400)
                .sorted(Comparator.comparingInt(Product::getPrice))
                .map(Product::getProductName)
                .collect(Collectors.toList());
    }
}

console打印:

[Banana, Headphones, Apple]
[Banana, Headphones, Apple]

Stream API 是对集合功能的增强,它提供了强大的数据处理能力。Stream 的一个重要特性是支持并行处理,能够充分利用多核处理器的优势,同时开发者无需关心底层的并行实现细节。

二、Stream API 常用操作

接下来我们通过具体示例介绍 Stream 的核心方法:

package com.example.stream;

import java.util.*;
import java.util.stream.Stream;

public class StreamOperations {

    public static void main(String[] args) {
        List<Product> productList = Arrays.asList(
                new Product("Laptop", false, 800, Product.Category.ELECTRONICS),
                new Product("Smartphone", false, 700, Product.Category.ELECTRONICS),
                new Product("T-Shirt", true, 400, Product.Category.CLOTHING),
                new Product("Jeans", true, 530, Product.Category.CLOTHING),
                new Product("Apple", true, 350, Product.Category.FOOD),
                new Product("Banana", true, 120, Product.Category.FOOD),
                new Product("Novel", true, 550, Product.Category.BOOKS),
                new Product("Headphones", false, 300, Product.Category.ELECTRONICS),
                new Product("Textbook", false, 450, Product.Category.BOOKS));

        System.out.println("Method 1 - Most expensive: " + findMostExpensive(productList));
        System.out.println("Method 2 - Most expensive: " + findMostExpensiveAlternative(productList));
        System.out.println("Has expensive items (>600): " + hasExpensiveItems(productList));
        System.out.println("All items affordable (>400): " + areAllAffordable(productList));
        System.out.println("---------------------------------------");

        // 创建 Stream 的两种方式
        Stream<Product> directStream = Stream.of(
                new Product("Camera", false, 600, Product.Category.ELECTRONICS),
                new Product("Tablet", false, 450, Product.Category.ELECTRONICS));
        directStream.forEach(System.out::println);
    }

    /**
     * 查找价格最高的商品名称 - 方式一
     */
    private static String findMostExpensive(List<Product> productList) {
        return productList.stream()
                .max(Comparator.comparingInt(Product::getPrice))
                .get()
                .getProductName();
    }

    /**
     * 查找价格最高的商品名称 - 方式二
     */
    private static String findMostExpensiveAlternative(List<Product> productList) {
        Optional<Product> maxProduct = productList.stream()
                .sorted((p1, p2) -> p2.getPrice() - p1.getPrice())
                .findFirst();
        return maxProduct.get().getProductName();
    }

    /**
     * 判断是否存在价格大于600的商品
     */
    private static boolean hasExpensiveItems(List<Product> productList) {
        return productList.stream().anyMatch(product -> product.getPrice() > 600);
    }

    /**
     * 判断所有商品价格是否都大于400
     */
    private static boolean areAllAffordable(List<Product> productList) {
        return productList.stream().allMatch(product -> product.getPrice() > 400);
    }
}

打印结果:

Method 1 - Most expensive: Laptop
Method 2 - Most expensive: Laptop
Has expensive items (>600): true
All items affordable (>400): false
---------------------------------------
Product{productName='Camera', inStock=false, price=600, category=ELECTRONICS}
Product{productName='Tablet', inStock=false, price=450, category=ELECTRONICS}

--

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。