北屯市网站建设_网站建设公司_测试上线_seo优化
2026/1/7 11:34:19 网站建设 项目流程

一、Java Stream流全面解析

1.1 Stream流概述

Stream是Java 8引入的API,用于以声明式方式处理数据集合。它允许以类似SQL语句的方式对数据进行操作,支持顺序和并行处理。

java

// Stream与传统集合操作对比 List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); // 传统方式 List<String> result1 = new ArrayList<>(); for (String name : names) { if (name.startsWith("A")) { result1.add(name.toUpperCase()); } } // Stream方式 List<String> result2 = names.stream() .filter(name -> name.startsWith("A")) .map(String::toUpperCase) .collect(Collectors.toList());

1.2 Stream创建方式

java

import java.util.*; import java.util.stream.*; public class StreamCreation { public static void main(String[] args) { // 1. 从集合创建 List<String> list = Arrays.asList("a", "b", "c"); Stream<String> stream1 = list.stream(); Stream<String> parallelStream = list.parallelStream(); // 2. 从数组创建 String[] array = {"a", "b", "c"}; Stream<String> stream2 = Arrays.stream(array); IntStream intStream = Arrays.stream(new int[]{1, 2, 3}); // 3. 使用Stream.of() Stream<String> stream3 = Stream.of("a", "b", "c"); Stream<Integer> stream4 = Stream.of(1, 2, 3); // 4. 生成无限流 Stream<Double> randomStream = Stream.generate(Math::random).limit(5); Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2).limit(5); // 5. 从文件创建 try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) { lines.forEach(System.out::println); } catch (IOException e) { e.printStackTrace(); } // 6. 使用Builder创建 Stream<String> builderStream = Stream.<String>builder() .add("a") .add("b") .add("c") .build(); } }

1.3 中间操作详解

1.3.1 筛选与切片

java

public class IntermediateOperations { public static void filterExample() { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // filter - 过滤 List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); // distinct - 去重 List<Integer> distinctNumbers = Arrays.asList(1, 2, 2, 3, 3, 3).stream() .distinct() .collect(Collectors.toList()); // limit - 限制数量 List<Integer> firstThree = numbers.stream() .limit(3) .collect(Collectors.toList()); // skip - 跳过元素 List<Integer> skipFirstThree = numbers.stream() .skip(3) .collect(Collectors.toList()); // takeWhile (Java 9+) - 当条件满足时取元素 List<Integer> takeWhile = numbers.stream() .takeWhile(n -> n < 5) .collect(Collectors.toList()); // dropWhile (Java 9+) - 当条件满足时丢弃元素 List<Integer> dropWhile = numbers.stream() .dropWhile(n -> n < 5) .collect(Collectors.toList()); } public static void mappingExample() { List<String> words = Arrays.asList("Java", "Stream", "API"); // map - 一对一转换 List<Integer> wordLengths = words.stream() .map(String::length) .collect(Collectors.toList()); // flatMap - 一对多转换并扁平化 List<String> letters = words.stream() .flatMap(word -> Arrays.stream(word.split(""))) .collect(Collectors.toList()); // mapToInt, mapToLong, mapToDouble - 转换为基本类型流 IntStream lengths = words.stream() .mapToInt(String::length); } }
1.3.2 排序操作

java

public class SortingOperations { public static void sortingExamples() { List<Student> students = Arrays.asList( new Student("Alice", 85), new Student("Bob", 92), new Student("Charlie", 78) ); // 自然排序 List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9); List<Integer> sortedNumbers = numbers.stream() .sorted() .collect(Collectors.toList()); // 自定义排序 List<Student> sortedByName = students.stream() .sorted(Comparator.comparing(Student::getName)) .collect(Collectors.toList()); // 多级排序 List<Student> sortedByScoreThenName = students.stream() .sorted(Comparator .comparing(Student::getScore).reversed() .thenComparing(Student::getName)) .collect(Collectors.toList()); } }

1.4 终端操作详解

1.4.1 匹配与查找

java

public class TerminalOperations { public static void matchExamples() { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // anyMatch - 任意匹配 boolean hasEven = numbers.stream() .anyMatch(n -> n % 2 == 0); // allMatch - 全部匹配 boolean allPositive = numbers.stream() .allMatch(n -> n > 0); // noneMatch - 没有匹配 boolean noNegative = numbers.stream() .noneMatch(n -> n < 0); // findFirst - 查找第一个 Optional<Integer> first = numbers.stream() .filter(n -> n > 3) .findFirst(); // findAny - 查找任意元素(并行流中更高效) Optional<Integer> any = numbers.parallelStream() .filter(n -> n > 3) .findAny(); } }
1.4.2 归约操作

java

public class ReductionOperations { public static void reduceExamples() { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // 求和 int sum = numbers.stream() .reduce(0, Integer::sum); // 求最大值 Optional<Integer> max = numbers.stream() .reduce(Integer::max); // 求最小值 Optional<Integer> min = numbers.stream() .reduce(Integer::min); // 连接字符串 List<String> words = Arrays.asList("Hello", "World", "!"); String sentence = words.stream() .reduce("", (a, b) -> a + " " + b); // 使用collect进行更复杂的归约 Map<Boolean, List<Integer>> partitioned = numbers.stream() .collect(Collectors.partitioningBy(n -> n % 2 == 0)); } }
1.4.3 收集器详解

java

public class CollectorsExamples { public static void collectionExamples() { List<Student> students = Arrays.asList( new Student("Alice", 85, "Math"), new Student("Bob", 92, "Math"), new Student("Charlie", 78, "Science"), new Student("David", 88, "Science") ); // 1. 转换为List List<String> names = students.stream() .map(Student::getName) .collect(Collectors.toList()); // 2. 转换为Set Set<String> subjects = students.stream() .map(Student::getSubject) .collect(Collectors.toSet()); // 3. 转换为Map Map<String, Integer> nameToScore = students.stream() .collect(Collectors.toMap( Student::getName, Student::getScore, (oldValue, newValue) -> newValue // 处理键冲突 )); // 4. 分组 Map<String, List<Student>> studentsBySubject = students.stream() .collect(Collectors.groupingBy(Student::getSubject)); // 5. 分区 Map<Boolean, List<Student>> partitioned = students.stream() .collect(Collectors.partitioningBy(s -> s.getScore() >= 85)); // 6. 连接字符串 String allNames = students.stream() .map(Student::getName) .collect(Collectors.joining(", ", "[", "]")); // 7. 统计 IntSummaryStatistics stats = students.stream() .collect(Collectors.summarizingInt(Student::getScore)); // 8. 自定义收集器 List<String> customCollect = students.stream() .collect(Collector.of( ArrayList::new, // supplier (list, student) -> list.add(student.getName()), // accumulator (list1, list2) -> { // combiner (用于并行流) list1.addAll(list2); return list1; }, Collector.Characteristics.IDENTITY_FINISH )); } }

1.5 数值流与并行流

java

public class SpecialStreams { public static void numericStreams() { // 数值流避免装箱拆箱开销 IntStream intStream = IntStream.rangeClosed(1, 100); // 求和 int sum = intStream.sum(); // 最大值 OptionalInt max = IntStream.of(1, 2, 3).max(); // 平均值 OptionalDouble avg = IntStream.of(1, 2, 3).average(); // 转换为对象流 Stream<Integer> boxed = IntStream.range(1, 5).boxed(); // 映射到数值流 int totalLength = Arrays.asList("Java", "Stream") .stream() .mapToInt(String::length) .sum(); } public static void parallelStreamExamples() { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 创建并行流 Stream<Integer> parallelStream = numbers.parallelStream(); // 顺序流转并行流 Stream<Integer> converted = numbers.stream().parallel(); // 并行计算示例 long count = numbers.parallelStream() .filter(n -> n % 2 == 0) .count(); // 注意:并行流不总是更快,需要考虑数据量和操作复杂度 // 对于小数据量或I/O密集型操作,顺序流可能更好 // 使用ForkJoinPool自定义线程池 ForkJoinPool customPool = new ForkJoinPool(4); customPool.submit(() -> { numbers.parallelStream() .map(n -> n * 2) .forEach(System.out::println); }); } }

二、Guava工具类全面解析

2.1 集合工具类

2.1.1 不可变集合

java

import com.google.common.collect.*; public class ImmutableCollections { public static void createImmutableCollections() { // 1. 创建不可变List ImmutableList<String> list1 = ImmutableList.of("a", "b", "c"); ImmutableList<String> list2 = ImmutableList.<String>builder() .add("a") .addAll(Arrays.asList("b", "c")) .build(); // 2. 创建不可变Set ImmutableSet<String> set1 = ImmutableSet.of("a", "b", "c"); ImmutableSet<String> set2 = ImmutableSet.copyOf(Arrays.asList("a", "b", "c")); // 3. 创建不可变Map ImmutableMap<String, Integer> map1 = ImmutableMap.of("a", 1, "b", 2); ImmutableMap<String, Integer> map2 = ImmutableMap.<String, Integer>builder() .put("a", 1) .put("b", 2) .build(); // 4. 不可变集合的优点:线程安全、节省内存、防止意外修改 } }
2.1.2 新集合类型

java

public class NewCollectionTypes { public static void multimapExample() { // Multimap: 一个键对应多个值 Multimap<String, String> multimap = ArrayListMultimap.create(); multimap.put("fruit", "apple"); multimap.put("fruit", "banana"); multimap.put("fruit", "orange"); multimap.put("color", "red"); Collection<String> fruits = multimap.get("fruit"); // [apple, banana, orange] Set<String> keys = multimap.keySet(); // [fruit, color] // 其他实现:HashMultimap, LinkedListMultimap, TreeMultimap } public static void bimapExample() { // BiMap: 双向Map,键值都唯一 BiMap<String, Integer> biMap = HashBiMap.create(); biMap.put("one", 1); biMap.put("two", 2); Integer oneValue = biMap.get("one"); // 1 String oneKey = biMap.inverse().get(1); // "one" // 强制唯一性:put时如果值已存在会抛出异常 // biMap.put("anotherOne", 1); // 抛出IllegalArgumentException // 使用forcePut覆盖 biMap.forcePut("anotherOne", 1); } public static void tableExample() { // Table: 二维表结构 Table<String, String, Integer> table = HashBasedTable.create(); table.put("row1", "col1", 1); table.put("row1", "col2", 2); table.put("row2", "col1", 3); Integer value = table.get("row1", "col2"); // 2 Map<String, Integer> row1 = table.row("row1"); // {col1=1, col2=2} Map<String, Integer> col1 = table.column("col1"); // {row1=1, row2=3} // 其他实现:TreeBasedTable, ArrayTable } public static void rangeSetExample() { // RangeSet: 区间集合 RangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Range.closed(1, 10)); // [1, 10] rangeSet.add(Range.closedOpen(15, 20)); // [15, 20) boolean contains5 = rangeSet.contains(5); // true boolean contains12 = rangeSet.contains(12); // false Range<Integer> range = rangeSet.rangeContaining(8); // [1, 10] } }
2.1.3 集合工具方法

java

public class CollectionUtilities { public static void utilitiesExamples() { // Lists工具类 List<String> list = Lists.newArrayList("a", "b", "c"); List<String> reversed = Lists.reverse(list); List<List<String>> partitions = Lists.partition(list, 2); // Sets工具类 Set<String> set1 = Sets.newHashSet("a", "b", "c"); Set<String> set2 = Sets.newHashSet("b", "c", "d"); Set<String> union = Sets.union(set1, set2); // [a, b, c, d] Set<String> intersection = Sets.intersection(set1, set2); // [b, c] Set<String> difference = Sets.difference(set1, set2); // [a] // Maps工具类 Map<String, Integer> map = Maps.newHashMap(); Map<String, Integer> synchronizedMap = Maps.synchronizedBiMap(HashBiMap.create()); // 过滤和转换集合 Collection<String> filtered = Collections2.filter(list, s -> s.startsWith("a")); Collection<Integer> transformed = Collections2.transform(list, String::length); } }

2.2 基础工具类

2.2.1 字符串处理

java

public class StringUtilities { public static void stringsExamples() { // Strings工具类 String nullToEmpty = Strings.nullToEmpty(null); // "" String emptyToNull = Strings.emptyToNull(""); // null boolean isNullOrEmpty = Strings.isNullOrEmpty(""); // true String padded = Strings.padEnd("123", 6, '0'); // "123000" String repeated = Strings.repeat("ab", 3); // "ababab" // Joiner Joiner joiner = Joiner.on("; ").skipNulls(); String joined = joiner.join("Harry", null, "Ron", "Hermione"); // "Harry; Ron; Hermione" // Splitter Splitter splitter = Splitter.on(',') .trimResults() .omitEmptyStrings(); Iterable<String> parts = splitter.split("foo,bar,, qux"); // ["foo", "bar", "qux"] // CaseFormat String lowerCamel = CaseFormat.UPPER_UNDERSCORE .to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME"); // "constantName" } }
2.2.2 前置条件检查

java

public class PreconditionsExample { public static void validateInput(String name, int age, Object obj) { // 基本检查 Preconditions.checkArgument(age >= 0, "年龄不能为负数: %s", age); Preconditions.checkNotNull(obj, "对象不能为空"); Preconditions.checkState(age < 150, "年龄不合理: %s", age); // 更复杂的检查 Preconditions.checkArgument( name != null && name.length() >= 2, "姓名必须至少2个字符: %s", name ); } public static void businessLogic(int value) { // 检查元素索引 List<String> list = Arrays.asList("a", "b", "c"); int index = 1; Preconditions.checkElementIndex(index, list.size()); // 检查位置索引 Preconditions.checkPositionIndex(index, list.size()); // 检查位置范围 Preconditions.checkPositionIndexes(0, 2, list.size()); } }

2.3 函数式编程

java

public class FunctionalProgramming { public static void functionExamples() { // Function Function<String, Integer> lengthFunction = new Function<String, Integer>() { @Override public Integer apply(String input) { return input.length(); } }; // 使用lambda简化 Function<String, Integer> lambdaFunction = String::length; // Predicate Predicate<String> lengthPredicate = new Predicate<String>() { @Override public boolean apply(String input) { return input.length() > 3; } }; // 组合函数 Function<Integer, Integer> times2 = x -> x * 2; Function<Integer, Integer> squared = x -> x * x; Function<Integer, Integer> composed = Functions.compose(times2, squared); Integer result = composed.apply(3); // 18 // 使用Suppliers Supplier<Double> randomSupplier = Suppliers.memoize(Math::random); Double random1 = randomSupplier.get(); Double random2 = randomSupplier.get(); // 两次调用返回相同值 } }

2.4 缓存工具

java

public class CacheExample { public static void cacheDemo() { // 创建缓存 LoadingCache<String, String> cache = CacheBuilder.newBuilder() .maximumSize(100) // 最大容量 .expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期 .expireAfterAccess(5, TimeUnit.MINUTES) // 访问后5分钟过期 .concurrencyLevel(4) // 并发级别 .recordStats() // 记录统计信息 .build( new CacheLoader<String, String>() { @Override public String load(String key) { // 当缓存不存在时,自动加载 return fetchFromDatabase(key); } } ); // 使用缓存 try { String value = cache.get("key1"); cache.put("key2", "value2"); cache.invalidate("key1"); cache.invalidateAll(); // 批量获取 Map<String, String> values = cache.getAll(Arrays.asList("key1", "key2")); // 获取统计信息 CacheStats stats = cache.stats(); double hitRate = stats.hitRate(); } catch (ExecutionException e) { e.printStackTrace(); } } private static String fetchFromDatabase(String key) { // 模拟数据库查询 return "value_for_" + key; } }

2.5 并发工具

java

public class ConcurrencyTools { public static void monitorExample() { // Monitor替代传统的synchronized Monitor monitor = new Monitor(); Monitor.Guard condition = new Monitor.Guard(monitor) { @Override public boolean isSatisfied() { return !queue.isEmpty(); } }; try { // 带有超时的等待 if (monitor.enterWhen(condition, 1, TimeUnit.SECONDS)) { try { // 执行操作 String item = queue.poll(); process(item); } finally { monitor.leave(); } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } public static void rateLimiterExample() { // 限流器 RateLimiter limiter = RateLimiter.create(5.0); // 每秒5个许可 // 获取许可(阻塞) limiter.acquire(); // 尝试获取许可(非阻塞) if (limiter.tryAcquire()) { // 执行操作 } // 批量获取 limiter.acquire(3); } public static void stripedExample() { // 分段锁,减少锁竞争 Striped<Lock> stripedLocks = Striped.lock(64); String resourceId = "resource1"; Lock lock = stripedLocks.get(resourceId); lock.lock(); try { // 操作共享资源 } finally { lock.unlock(); } } }

三、Stream与Guava结合的最佳实践

3.1 性能优化组合

java

public class PerformanceOptimization { public static void optimizedOperations() { List<String> data = Lists.newArrayList("a", "b", "c", "d", "e"); // 1. 使用不可变集合加速 ImmutableList<String> immutableData = ImmutableList.copyOf(data); // 2. Stream与Guava缓存结合 LoadingCache<String, String> cache = CacheBuilder.newBuilder() .maximumSize(1000) .build(CacheLoader.from(String::toUpperCase)); List<String> processed = immutableData.stream() .map(key -> { try { return cache.get(key); } catch (ExecutionException e) { throw new RuntimeException(e); } }) .collect(Collectors.toList()); // 3. 并行处理大集合 Map<String, Long> frequencyMap = immutableData.parallelStream() .collect(Collectors.groupingByConcurrent( Function.identity(), Collectors.counting() )); } }

3.2 数据处理管道

java

public class DataProcessingPipeline { public static class DataProcessor { private final List<Function<String, String>> processors; public DataProcessor() { this.processors = Lists.newArrayList(); } public DataProcessor addProcessor(Function<String, String> processor) { processors.add(processor); return this; } public Stream<String> process(Stream<String> input) { return input.map(data -> { String result = data; for (Function<String, String> processor : processors) { result = processor.apply(result); } return result; }); } } public static void pipelineExample() { DataProcessor processor = new DataProcessor() .addProcessor(String::trim) .addProcessor(String::toUpperCase) .addProcessor(s -> s.replace(" ", "_")); List<String> input = Arrays.asList(" hello world ", " java stream "); List<String> output = processor.process(input.stream()) .collect(Collectors.toList()); } }

3.3 复杂业务逻辑处理

java

public class BusinessLogic { static class Order { String customerId; double amount; String status; // getters and setters } public static void processOrders(List<Order> orders) { // 使用Guava的Multimap分组 Multimap<String, Order> ordersByCustomer = ArrayListMultimap.create(); orders.forEach(order -> ordersByCustomer.put(order.customerId, order)); // 使用Stream处理每个客户的订单 Map<String, Double> customerTotal = ordersByCustomer.keySet().stream() .collect(Collectors.toMap( customerId -> customerId, customerId -> ordersByCustomer.get(customerId).stream() .mapToDouble(order -> order.amount) .sum() )); // 使用Guava的Table进行多维分析 Table<String, String, Double> analysisTable = HashBasedTable.create(); orders.forEach(order -> { analysisTable.put( order.customerId, order.status, analysisTable.get(order.customerId, order.status) != null ? analysisTable.get(order.customerId, order.status) + order.amount : order.amount ); }); } }

四、常见问题与解决方案

4.1 Stream常见陷阱

java

public class StreamPitfalls { public static void commonMistakes() { // 1. 多次使用同一个Stream Stream<String> stream = Stream.of("a", "b", "c"); stream.forEach(System.out::println); // OK // stream.forEach(System.out::println); // 错误!Stream已被消费 // 2. 无限流忘记限制 // Stream.iterate(0, i -> i + 1).forEach(System.out::println); // 无限循环 // 3. 并行流中的副作用 List<String> list = new ArrayList<>(); Stream.of("a", "b", "c").parallel().forEach(list::add); // 线程不安全! // 正确方式 List<String> safeList = Stream.of("a", "b", "c") .parallel() .collect(Collectors.toList()); // 4. 自动装箱性能问题 IntStream.range(1, 1000) // 使用基本类型流 .sum(); // 性能更好 } }

4.2 性能优化建议

java

public class PerformanceTips { public static void optimizationTips() { // 1. 使用基本类型流避免装箱 long sum = LongStream.rangeClosed(1, 1_000_000) .sum(); // 比Stream<Long>快 // 2. 短路操作优化 boolean hasLargeNumber = IntStream.range(1, 1_000_000) .anyMatch(n -> n > 500_000); // 找到就停止 // 3. 预分配集合大小 List<String> list = Lists.newArrayListWithCapacity(1000); // 4. 使用并行流的条件 // - 数据量足够大(至少10,000个元素) // - 操作是计算密集型 // - 流源容易分割(如ArrayList) // 5. 缓存重复计算 Map<Integer, Boolean> cache = Maps.newHashMap(); boolean result = cache.computeIfAbsent(123, this::expensiveOperation); } private static boolean expensiveOperation(int input) { // 耗时操作 return true; } }

总结

Java Stream API和Guava库是现代Java开发中不可或缺的工具。Stream提供了声明式的数据处理能力,而Guava则提供了丰富的工具类和扩展功能。通过合理组合使用这两者,可以:

  1. 编写更简洁、易读的代码

  2. 提高代码的性能和可维护性

  3. 处理复杂的业务逻辑

  4. 减少重复代码

  5. 提高代码的安全性和稳定性

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询