深入探讨Java Stream技术:优雅、高效的数据处理

深入理解Java Stream:优雅而强大的数据处理

在Java编程世界中,数据处理是一个不可避免的任务。为了更高效、更简洁地处理数据,Java 8引入了Stream API。Stream API 提供了一种新的抽象,使得我们可以以一种更函数式的方式处理集合数据。在本文中,我们将深入探讨Java Stream的一些常用方法,以及它们如何使得数据处理变得更加优雅和强大。

什么是Java Stream?

Java Stream是一种用于处理集合数据的API,它引入了一种新的抽象,让我们能够以声明式的方式处理数据。与传统的集合操作方式相比,Stream API提供了更高层次、更函数式的操作。

基础概念

在开始介绍常用方法之前,让我们先了解一些Java Stream的基础概念。

流的创建

要使用流,首先需要从一个数据源创建它。常见的数据源包括集合、数组、I/O通道等。下面是一些创建流的方式:

List<String> myList = Arrays.asList("apple", "orange", "banana");
Stream<String> streamFromList = myList.stream();int[] array = {1, 2, 3, 4, 5};
IntStream streamFromArray = Arrays.stream(array);

中间操作和终端操作

流的操作可以分为中间操作和终端操作。中间操作返回一个新的流,可以通过链式调用多个中间操作。终端操作触发流的遍历,并生成最终的结果。

List<String> result = myList.stream().filter(s -> s.startsWith("a")).map(String::toUpperCase).collect(Collectors.toList());

上述代码中,filtermap 是中间操作,而 collect 是终端操作。

常用方法

1. filter

filter 方法用于过滤流中的元素,接受一个Predicate作为参数,返回一个新的流。

List<String> filteredList = myList.stream().filter(s -> s.length() > 5).collect(Collectors.toList());

2. map

map 方法用于对流中的每个元素应用一个函数,将其映射成一个新的元素。

List<Integer> lengths = myList.stream().map(String::length).collect(Collectors.toList());

3. forEach

forEach 方法对流中的每个元素执行指定的操作,通常用于遍历流。

myList.stream().forEach(System.out::println);

4. collect

collect 方法是一个终端操作,将流中的元素收集到一个结果容器中,比如List、Set或Map。

List<String> collectedList = myList.stream().filter(s -> s.length() > 5).collect(Collectors.toList());

5. reduce

reduce 方法可以将流中的元素组合起来,产生一个新的值。它接受一个初始值和一个BinaryOperator。

Optional<String> concatenated = myList.stream().reduce((s1, s2) -> s1 + s2);

当使用Java Stream进行数据处理时,除了上述提到的常用方法外,还有一些其他有趣和强大的方法,让我们继续深入探讨。

6. flatMap

flatMap 方法用于将一个流中的每个元素都转换为另一个流,然后将这些流连接起来。它常用于处理嵌套的集合结构。

List<List<String>> nestedList = Arrays.asList(Arrays.asList("apple", "banana"),Arrays.asList("orange", "grape"),Arrays.asList("melon", "peach")
);List<String> flatMapResult = nestedList.stream().flatMap(Collection::stream).collect(Collectors.toList());

7. distinct

distinct 方法用于去除流中重复的元素,根据元素的自然顺序或者通过自定义的比较器来进行判定。

List<String> distinctList = myList.stream().distinct().collect(Collectors.toList());

8. sorted

sorted 方法用于对流中的元素进行排序。可以使用自然排序或者通过传递一个自定义的比较器。

List<String> sortedList = myList.stream().sorted().collect(Collectors.toList());

9. limitskip

limit 方法用于截取流中的前 N 个元素,而 skip 方法则用于跳过流中的前 N 个元素。

List<String> limitedList = myList.stream().limit(3).collect(Collectors.toList());List<String> skippedList = myList.stream().skip(2).collect(Collectors.toList());

10. anyMatchallMatchnoneMatch

这些方法用于检查流中的元素是否满足某个条件。anyMatch 判断是否至少有一个元素满足条件,allMatch 判断是否所有元素都满足条件,而 noneMatch 判断是否所有元素都不满足条件。

boolean anyMatchResult = myList.stream().anyMatch(s -> s.startsWith("a"));boolean allMatchResult = myList.stream().allMatch(s -> s.length() > 3);boolean noneMatchResult = myList.stream().noneMatch(s -> s.contains("z"));

1. 自定义操作符

Java Stream API允许我们自定义操作符以满足特定的需求。通过 mapflatMap 结合自定义的函数,可以创建强大的操作符。

例如,假设我们想要一个操作符,将每个字符串转换为它的首字母,并返回一个新的流:

List<Character> firstLetters = myList.stream().map(s -> s.charAt(0)).collect(Collectors.toList());

12. joining

joining 是一个终端操作,用于连接流中的元素。这在处理字符串时特别有用。

String result = myList.stream().collect(Collectors.joining(", "));

上述代码将流中的字符串用逗号和空格连接成一个字符串。

13. groupingBypartitioningBy

groupingBy 方法用于按照某个条件对流中的元素进行分组,返回一个 Map。而 partitioningBy 则是 groupingBy 的一种特殊情况,根据条件将流分为两组。

Map<Integer, List<String>> groupedByLength = myList.stream().collect(Collectors.groupingBy(String::length));Map<Boolean, List<String>> partitioned = myList.stream().collect(Collectors.partitioningBy(s -> s.length() > 3));

14. 并行流

Java Stream 还提供了并行流的支持,充分发挥多核处理器的优势,加速数据处理。只需在流的创建过程中调用 parallel() 方法即可将流转换为并行流。

List<String> parallelResult = myList.parallelStream().filter(s -> s.length() > 5).collect(Collectors.toList());

15. 异步操作

通过 CompletableFuture 结合 supplyAsync 方法,我们可以异步处理流中的元素,提高程序的性能。

CompletableFuture<List<String>> futureResult = CompletableFuture.supplyAsync(() ->myList.stream().filter(s -> s.length() > 5).collect(Collectors.toList())
);

16. reduce 的更多应用

reduce 方法除了用于组合元素外,还可以用于执行更复杂的归约操作。例如,计算集合中所有字符串的总长度:

int totalLength = myList.stream().map(String::length).reduce(0, Integer::sum);

上述代码中,map 将每个字符串映射为它的长度,然后 reduce 方法对这些长度进行求和。

17. findFirstfindAny

findFirst 用于找到流中的第一个元素,而 findAny 则返回流中的任意一个元素。这在需要获取满足条件的第一个元素时非常有用。

Optional<String> firstElement = myList.stream().findFirst();Optional<String> anyElement = myList.stream().findAny();

18. peek

peek 方法用于在流的每个元素执行操作时生成一个新的流,通常用于调试和理解流的中间操作过程。

List<String> peekedValues = myList.stream().peek(s -> System.out.println("Processing element: " + s)).collect(Collectors.toList());

19. 自定义收集器

除了提供的预定义收集器外,Java Stream API还允许我们创建自定义的收集器,以满足特定的需求。这需要实现 Collector 接口的三个方法:supplieraccumulatorcombiner

20. 异常处理

在流的处理过程中,如果希望捕获并处理异常,可以使用 try-catch 块或者 exceptionally 方法。

List<String> resultList = myList.stream().map(s -> {try {return someMethodThatThrowsException(s);} catch (Exception e) {// Handle exceptionreturn defaultValue;}}).collect(Collectors.toList());

21. 自定义过滤器

除了内置的 filter 方法外,我们还可以创建自定义的过滤器,以便更灵活地处理流中的元素。这可以通过实现 Predicate 接口来实现。

public class CustomFilter implements Predicate<String> {@Overridepublic boolean test(String s) {// 自定义过滤逻辑return s != null && s.length() > 3;}
}// 使用自定义过滤器
List<String> customFilteredList = myList.stream().filter(new CustomFilter()).collect(Collectors.toList());

这样,我们可以根据项目的需求轻松创建各种自定义的过滤器。

22. 处理空值

在实际应用中,我们经常需要处理可能为空的数据。Java Stream 提供了 Optional 类型,使得我们能够更好地处理可能为空的元素。

List<String> nonNullValues = myList.stream().map(Optional::ofNullable).flatMap(Optional::stream).collect(Collectors.toList());

在这个例子中,ofNullable 方法将元素包装成 Optional,然后通过 flatMap 过滤掉空值。

23. 并行流的注意事项

虽然并行流能够加速处理,但在使用时需要注意共享状态和线程安全的问题。确保对共享变量的修改是线程安全的,以避免潜在的并发问题。

24. 使用 Stream 构建器

Java 9 引入了 Stream.Builder 接口,使得我们可以更方便地构建流,特别是在需要动态添加元素的情况下。

Stream.Builder<String> builder = Stream.builder();
builder.accept("apple");
builder.accept("orange");
builder.accept("banana");Stream<String> fruits = builder.build();

25. 组合多个流

Stream.concat 方法允许我们将两个流合并成一个流。


Stream<String> combinedStream = Stream.concat(stream1, stream2);

这可以用于组合多个数据源或者处理多个流的情况。

26. 时间和日期处理

在Java 8之后,引入了LocalDateLocalTimeLocalDateTime等新的日期时间类,结合Java Stream,我们可以更便捷地处理时间序列数据。

List<LocalDate> dateList = Arrays.asList(LocalDate.of(2023, 1, 1),LocalDate.of(2023, 2, 1),LocalDate.of(2023, 3, 1)
);List<LocalDate> filteredDates = dateList.stream().filter(date -> date.isAfter(LocalDate.now())).collect(Collectors.toList());

27. 收集统计信息

Java Stream API提供了Collectors类,其中包含了一些有用的收集器。例如,Collectors.summarizingInt可以用于汇总统计信息,如最大值、最小值、平均值和总和。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);IntSummaryStatistics stats = numbers.stream().collect(Collectors.summarizingInt(Integer::intValue));System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());
System.out.println("Average: " + stats.getAverage());
System.out.println("Sum: " + stats.getSum());

28. 与 Map 的结合运用

结合Map的功能,我们可以更灵活地对流进行分组、分区或者进行其他复杂的操作。

Map<Integer, List<String>> lengthGroup = myList.stream().collect(Collectors.groupingBy(String::length));Map<Boolean, List<String>> partitionedMap = myList.stream().collect(Collectors.partitioningBy(s -> s.length() > 3));

29. 自定义排序

除了 sorted 方法提供的排序方式外,我们还可以使用 Comparator 接口自定义排序规则。

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

30. Stream API 的延迟执行

Stream API支持延迟执行,只有在终端操作被调用时,中间操作才会开始执行。这种特性允许我们构建更为高效的数据处理流程。

Stream<String> lazyStream = myList.stream().filter(s -> s.length() > 3).map(String::toUpperCase);// 终端操作触发中间操作的执行
List<String> result = lazyStream.collect(Collectors.toList());

31. 文件处理与IO操作

Java Stream API也可以与文件IO结合使用,提供了便捷的方式来处理文件中的数据。例如,我们可以通过Files.lines方法获取文件中的所有行,并进行进一步的处理:

try {Stream<String> lines = Files.lines(Paths.get("example.txt"));List<String> filteredLines = lines.filter(line -> line.contains("Java")).collect(Collectors.toList());lines.close();
} catch (IOException e) {e.printStackTrace();
}

32. 自定义收集器进阶

除了常见的收集器外,我们还可以通过Collector.of方法创建自定义的收集器,以满足更灵活的需求。这种方式可以用于实现一些特定的数据结构或者聚合操作。

Collector<MyObject, StringBuilder, String> myCollector =Collector.of(StringBuilder::new,(result, element) -> result.append(element.getName()).append(", "),StringBuilder::append,StringBuilder::toString);String result = myList.stream().collect(myCollector);

33. 操作流的元数据

通过countanyMatchallMatch等方法,我们可以获取关于流的元数据信息,例如流中元素的数量、是否存在满足某条件的元素等。

long count = myList.stream().count();boolean anyMatch = myList.stream().anyMatch(s -> s.startsWith("a"));boolean allMatch = myList.stream().allMatch(s -> s.length() > 2);

34. 自定义并行度

在处理大规模数据时,我们可以通过指定自定义的并行度来优化性能。通过parallelStream方法的参数,我们可以控制并行度的级别。

List<String> parallelResult = myList.parallelStream().withParallelism(4) // 自定义并行度.filter(s -> s.length() > 5).collect(Collectors.toList());

35. 多级分组和多级映射

Collectors.groupingBy 方法支持多级分组,而 Collectors.mapping 方法支持多级映射。这使得我们可以更复杂地组织和处理数据。

Map<Integer, Map<Character, List<String>>> groupedByLengthAndFirstChar = myList.stream().collect(Collectors.groupingBy(String::length,Collectors.groupingBy(s -> s.charAt(0))));

36. 使用 Collectors.toMap 进行自定义映射

在收集流元素到Map时,Collectors.toMap 允许我们指定键和值的映射关系。这对于从流中构建自定义的映射结构非常有用。

Map<Integer, String> lengthToNameMap = myList.stream().collect(Collectors.toMap(String::length, Function.identity()));

这里使用了 Function.identity() 作为值映射,表示使用元素本身作为值。

37. 创建无限流

Java Stream API允许我们创建无限流,这对于模拟数据流或者处理动态生成的数据非常有用。例如,生成一个无限递增的整数流:


Stream<Integer> infiniteStream = Stream.iterate(0, i -> i + 1);

38. 并行流的线程池定制

通过 ForkJoinPool 可以为并行流提供自定义的线程池,以更好地控制并行执行的行为。

ForkJoinPool customThreadPool = new ForkJoinPool(4); // 4是并行度
List<String> parallelResult = myList.parallelStream().withExecutor(customThreadPool).filter(s -> s.length() > 5).collect(Collectors.toList());

39. 使用 Files.walk 处理目录

Files.walk 方法允许我们在目录中递归地处理文件。结合流操作,我们可以方便地筛选和处理目录中的文件。

try {Stream<Path> filePaths = Files.walk(Paths.get("directoryPath"));List<String> fileNames = filePaths.filter(Files::isRegularFile).map(Path::getFileName).map(Path::toString).collect(Collectors.toList());filePaths.close();
} catch (IOException e) {e.printStackTrace();
}

40. 使用 IntStreamDoubleStreamLongStream

除了通用的 Stream 接口,Java Stream API还提供了专门用于处理原始数据类型的流。这可以提高性能,并减少装箱拆箱的开销。

IntStream.rangeClosed(1, 5).forEach(System.out::println);DoubleStream.of(1.0, 2.0, 3.0).map(d -> d * 2).forEach(System.out::println);

41. 使用 flatMap 处理嵌套结构

flatMap 不仅用于处理集合类型,还可以处理嵌套结构,例如列表中包含了另一层的列表。这时,flatMap 可以将多层结构扁平化,方便后续的操作。

List<List<String>> nestedList = Arrays.asList(Arrays.asList("apple", "banana"),Arrays.asList("orange", "grape"),Arrays.asList("melon", "peach")
);List<String> flatMapResult = nestedList.stream().flatMap(Collection::stream).collect(Collectors.toList());

42. 自定义并发操作

对于并行流,我们可以使用 parallel() 方法开启并行处理。但有时我们可能需要更精细的控制,并在某一步骤中执行自定义的并发操作。

List<String> parallelResult = myList.stream().unordered().parallel().filter(s -> s.length() > 5).collect(Collectors.toList());

通过 unordered() 方法,我们告诉流操作不依赖元素的顺序,这有助于提高并行执行的效率。

43. 使用 Arrays.stream 处理数组

对于数组,我们可以使用 Arrays.stream 方法将数组转换为流,方便利用流的操作。

int[] array = {1, 2, 3, 4, 5};
IntStream streamFromArray = Arrays.stream(array);
int sum = streamFromArray.sum();

44. 操作原始类型的 Optional

Optional 类型不仅可以用于对象类型,还可以用于原始类型。例如,OptionalIntOptionalDoubleOptionalLong

OptionalInt max = IntStream.of(1, 2, 3, 4, 5).max();int maxValue = max.orElse(0);

45. 使用 Stream.generate 创建无限流

Stream.generate 方法允许我们使用提供的 Supplier 生成无限流。这对于需要模拟或生成数据流的情况非常有用。

Stream<String> randomStrings = Stream.generate(() ->UUID.randomUUID().toString().substring(0, 8));

46. 使用 Stream.iterate 实现斐波那契数列

通过 Stream.iterate 方法,我们可以生成无限流。利用这一特性,我们可以非常简洁地生成斐波那契数列。

Stream.iterate(new int[]{0, 1}, fib -> new int[]{fib[1], fib[0] + fib[1]}).limit(10).mapToInt(fib -> fib[0]).forEach(System.out::println);

47. 自定义收集器进阶应用

在自定义收集器时,我们可以实现更复杂的逻辑,例如在收集过程中进行聚合或者其他特殊处理。

List<String> customizedCollection = myList.stream().collect(CustomCollector::new,CustomCollector::accumulate,CustomCollector::combine).finisher();

这里 CustomCollector 是一个自定义的收集器。

48. 使用 Stream.concat 合并多个流

Stream.concat 方法可以用于合并两个流。这对于在处理不同来源的数据时,能够更为灵活地组合多个流。

Stream<String> stream1 = Stream.of("apple", "banana");
Stream<String> stream2 = Stream.of("orange", "grape");Stream<String> combinedStream = Stream.concat(stream1, stream2);

49. 创建自定义的流源

除了集合、数组、文件等已有的数据源,我们还可以通过实现 Spliterator 接口,自定义流的源头。

public class CustomSpliterator implements Spliterator<String> {// 实现Spliterator接口的方法
}Stream<String> customStream = StreamSupport.stream(new CustomSpliterator(), false);

50. 使用 peek 进行调试

peek 方法用于在流的每个元素上执行操作,通常用于调试和理解流的中间操作过程。这对于在流处理过程中输出中间结果非常有帮助。

List<String> peekedValues = myList.stream().peek(s -> System.out.println("Processing element: " + s)).collect(Collectors.toList());

51. 使用 Collectors.collectingAndThen 完善收集过程

Collectors.collectingAndThen 方法允许我们在收集完成后应用一些额外的转换。这对于在收集完成后执行最后一步处理非常有用。

List<String> result = myList.stream().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));

上述例子中,使用 collectingAndThen 将得到的 List 转为不可修改的列表。

52. 使用 Stream.concat 合并多个流

Stream.concat 方法可以用于合并两个流。这对于在处理不同来源的数据时,能够更为灵活地组合多个流。

Stream<String> stream1 = Stream.of("apple", "banana");
Stream<String> stream2 = Stream.of("orange", "grape");Stream<String> combinedStream = Stream.concat(stream1, stream2);

53. 处理多个 Optional

Optional 提供了一些方法,可以更方便地处理多个 Optional 对象。

Optional<String> optional1 = Optional.of("Hello");
Optional<String> optional2 = Optional.of("World");Optional<String> result = optional1.flatMap(s1 ->optional2.map(s2 -> s1 + " " + s2));

这种方式避免了使用多层嵌套的 ifPresentisPresent 判断。

54. 使用 IntStream 处理日期范围

在处理日期范围时,可以使用 IntStream 生成日期的整数表示,再转为日期对象。

LocalDate startDate = LocalDate.of(2023, 1, 1);
LocalDate endDate = LocalDate.of(2023, 12, 31);IntStream.range(0, ChronoUnit.DAYS.between(startDate, endDate)).mapToObj(startDate::plusDays).forEach(System.out::println);

55. 处理重复元素

通过 Collectors.toSet 或者 Collectors.toMap 可以轻松去除流中的重复元素。

List<String> distinctList = myList.stream().distinct().collect(Collectors.toList());

56. 使用 Stream.iterate 实现无限递增序列

通过 Stream.iterate 方法,我们可以生成无限递增的序列。这对于模拟或生成一系列数字非常有用。

Stream.iterate(0, i -> i + 2).limit(10).forEach(System.out::println);

上述例子中,我们生成了一个包含前10个偶数的序列。

57. 使用 Stream.of 处理多个元素

Stream.of 方法可以接受多个元素,这样我们可以轻松地创建一个包含多个元素的流。


Stream<String> stringStream = Stream.of("apple", "banana", "orange");

58. 使用 IntStream.range 生成范围内的整数

IntStream.range 方法用于生成一个范围内的整数序列。这对于需要处理一系列整数的情况非常方便。

IntStream.range(1, 6).forEach(System.out::println);

上述例子中,我们生成了一个包含1到5的整数序列。

59. 使用 Files.lines 读取文件内容

Files.lines 方法可以用于轻松读取文件的内容并将其转化为流。这在处理大型文本文件时非常有用。

try {Stream<String> fileLines = Files.lines(Paths.get("example.txt"));fileLines.forEach(System.out::println);fileLines.close();
} catch (IOException e) {e.printStackTrace();
}

60. 使用 Collectors.reducing 进行更复杂的归约

Collectors.reducing 方法允许我们进行更复杂的归约操作,可以自定义归约的初始值、累加器和组合器。

Optional<String> concatenatedString = myList.stream().collect(Collectors.reducing((s1, s2) -> s1 + s2));

61. 使用 Stream.generate 生成随机数流

Stream.generate 方法允许我们生成一个无限的随机数流。结合 Random 类,我们可以轻松模拟或处理一系列随机数据。

Random random = new Random();
Stream<Integer> randomStream = Stream.generate(random::nextInt);

62. 使用 Collectors.partitioningBy 分区数据

Collectors.partitioningBy 方法用于将流中的元素根据条件分成两个部分,返回一个 Map<Boolean, List<T>>

Map<Boolean, List<String>> partitionedMap = myList.stream().collect(Collectors.partitioningBy(s -> s.length() > 3));

63. 使用 Stream.concat 合并数组流

Stream.concat 不仅可以合并两个流,还可以合并数组的流。这对于在处理多个数组时更为方便。

String[] array1 = {"apple", "banana"};
String[] array2 = {"orange", "grape"};Stream<String> combinedStream = Stream.concat(Arrays.stream(array1), Arrays.stream(array2));

64. 使用 IntStream 处理并行计算

IntStream 类提供了一系列用于处理原始 int 类型数据的方法。在并行计算时,使用 parallel 方法可以提高性能。

int sum = IntStream.rangeClosed(1, 1000).parallel().sum();

65. 使用 Stream.iterate 创建斐波那契元组

利用 Stream.iterate 方法,我们可以创建一个斐波那契数列的元组流,其中每个元组包含相邻的两个斐波那契数。

Stream.iterate(new int[]{0, 1}, fib -> new int[]{fib[1], fib[0] + fib[1]}).limit(10).forEach(tuple -> System.out.println("(" + tuple[0] + ", " + tuple[1] + ")"));

通过继续深入学习和实践这些技巧,你将更加游刃有余地应对不同的数据处理场景。这些方法和工具的灵活性使得Java Stream API成为处理集合和流数据的强大工具。愿你在使用这些技术的过程中取得更多的成就,不断提升自己的编程技能!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/190119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贝叶斯网络 (期末复习)

文章目录 贝叶斯网络&#xff08;概率图模型&#xff09;定义主要考点例题- 要求画出贝叶斯网络图- 计算各节点的条件概率表- 计算概率-分析独立性 贝叶斯网络&#xff08;概率图模型&#xff09; 定义 一种简单的用于表示变量之间条件独立性的有向无环图&#xff08;DAG&…

一线大厂Redis高并发缓存架构(待完善)

场景1&#xff1a;秒杀库存场景&#xff0c; 10000人抢100个商品 如果用普通的分布式锁实现&#xff0c; 最后抢到的人&#xff0c;要等前面99个人抢完 优化方案&#xff1a;可用分段锁&#xff0c; 降低锁的粒度&#xff0c; 比如1-10库存用锁product:101_1,11-20库存用锁pr…

MySQL -DDL 及表类型

DDL 创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification:[DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name 1.CHARACTER SET&#xff1a…

PT读spef报PARA-006如何解决?

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 There are multiple causes that can trigger PARA-006 errors. Here is a checklist. 1) SPEF reading order Functionally, the parasitic files can be read in any order. For best stitching…

acwing算法基础之动态规划--数位统计DP、状态压缩DP、树形DP和记忆化搜索

目录 1 基础知识2 模板3 工程化 1 基础知识 暂无。。。 2 模板 暂无。。。 3 工程化 题目1&#xff1a;求a~b中数字0、数字1、…、数字9出现的次数。 思路&#xff1a;先计算1~a中每位数字出现的次数&#xff0c;然后计算1~b-1中每位数字出现的次数&#xff0c;两个相减即…

C++基础 -29- 友元类

友元类格式 friend class person2;类的友元类访问类的全部成员 #include "iostream"using namespace std;class person1 { public:int a;protected:int b;private:int c;friend class person2; };class person2 { public:void test(){person1 a;a.a 100;a.b 200…

校园局域网规划与设计(cisco仿真模拟)

摘 要 随着网络技术的发展&#xff0c;校园网的建设已经进入到一个蓬勃发展的阶段。校园网的建成和使用&#xff0c;对于提高教学和科研的质量、改善教学和科研条件、加快学校的信息化进程&#xff0c;开展多媒体教学与研究以及使教学多出人才、科研多出成果有着十分重要而深远…

05-建造者模式-C语言实现

UML类图&#xff1a; 代码实现&#xff1a; #include <stdio.h> #include <stdlib.h>// 产品类 typedef struct {char* part1;char* part2;char* part3; } Product;// 抽象建造者类 typedef struct {void (*buildPart1)(void*, const char*);void (*buildPart2)(v…

leetCode 494.递增子序列 + 回溯算法 + 图解 + 笔记

给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;也可以视作递增序列的一种特殊情况。 示例 1&#…

Python项目管理利器poetry我愿称之为神!

MongoDB是一种流行的NoSQL数据库&#xff0c;它以灵活的文档结构存储数据。MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包&#xff0c;你可以从MongoDB官网下载安装&#xff0c;MongoDB 预编译二进制包下载地址&#xff1a; https://www.mongodb.com/try/download/…

【Linux】信号概念和信号的产生

文章目录 一、什么是信号&#xff1f;1.signal系统调用2.从硬件解析键盘数据如何输入给内核3.同步和异步 二、信号的产生1.键盘组合键2. kill命令3.系统调用接口3.1kill3.2 raise3.3abort 4.异常5.软件条件 重谈core dump标志位 一、什么是信号&#xff1f; 以日常为例&#x…

Echarts 扇形百分比算法(最大余额法)

主要用于计算一个数组中某个值占总和的百分比&#xff0c;并且保留指定的小数位数 function getPercentValue(arrList, index, precision) { // arrList要计算数据的数组 // index要计算数组中值的下表 // precision百分比保留几位小数&#xff0c;默认保留2位小数 // 判断是否…

Elasticsearch:么是向量嵌入?

向量嵌入定义 向量嵌入 (vector embeddings) 是一种将单词、句子和其他数据转换为捕获其含义和关系的数字的方法。 它们将不同的数据类型表示为多维空间中的点&#xff0c;其中相似的数据点更紧密地聚集在一起。 这些数字表示可以帮助机器更有效地理解和处理这些数据。 单词和…

VS安装QT VS Tools编译无法通过

场景&#xff1a; 项目拷贝到虚拟机内部后&#xff0c;配置好相关环境后无法编译&#xff0c;安装QT VS Tools后依旧无法编译&#xff0c;查找资料网上说的是QT工具版本不一致导致的&#xff0c;但反复试了几个版本后依旧无法编译通过。错误信息如下&#xff1a; C:\Users\Ad…

OpenTelemetry系列 - 第1篇 相关概念

目录 一、背景二、概念2.1 Traces & Span2.2 Metrics2.3 Logs2.4 Baggage2.5 OTel2.6 OTLP2.7 Resources2.8 Instrumentation Scope2.9 Sampling 三、核心组件 一、背景 OpenTelemetry是一个可观察性框架和工具包&#xff0c;旨在创建和管理遥测数据&#xff0c;如跟踪、指…

Monocle 3 | 太牛了!单细胞必学R包!~(五)(差异分析之聚类比较与模块鉴定)

1写在前面 准备出去玩耍了&#xff0c;今天就不废话了&#xff0c;直接上主题吧。&#x1f973; monocle3做差异分析也是牛的一米&#xff01;~&#x1f33e; 2用到的包 rm(list ls())library(tidyverse)library(monocle3) 3示例数据 我们还是载入之前用过的一个数据集吧。&am…

Python 爬虫 一切都可爬,我爬我爬我还爬。你想要啥数据,来找我呀!

1. 什么是Python爬虫&#xff1f; Python爬虫是一种自动化程序&#xff0c;可以从互联网上获取信息并提取数据。通过模拟网页浏览器的行为&#xff0c;爬虫可以访问网页、抓取数据、解析内容&#xff0c;并将其保存到本地或用于进一步分析 2. 爬虫的合法性问题 使用Python爬虫…

Rust语言入门教程(十二) - 枚举类型Enums与模式匹配

枚举类型与模式匹配 欢迎使用并贡献我的开源webhook工具: https://github.com/owenchenxy/rusthook/什么是枚举类型 在Rust中, 枚举(Enums)类型更接近Haskell中的代数数据类型,而不是类似于C语言中的枚举类型。 定义一个枚举类型的步骤如下: 以enum关键字开头;后面紧接该…

HarmonyOs 4 (三) ArkTS语言

目录 一 认识ArkTs语言1.1 ArkTs1.2 基本结构 二 基本语法2.1 声明式UI2.1.1 创建组件2.1.1.1 无参数2.1.1.2 有参数2.1.1.3 组件样式2.1.1.4 组件方法2.1.1.5 组件嵌套 2.1.2 自定义组件2.1.2.1 基本结构2.1.2.2 成员函数/变量2.1.2.3 自定义组件的参数规定2.1.2.4 Build函数2…

高效转码工具Compressor for Mac,让视频处理更轻松

在现如今的数字时代&#xff0c;视频内容已经成为人们生活中不可或缺的一部分。无论是在社交媒体上分享生活点滴&#xff0c;还是在工作中制作专业的营销视频&#xff0c;我们都希望能够以高质量、高效率地处理和传输视频文件。而Compressor for Mac作为一款强大的视频转码工具…