1.filter 是 Java 8 中 Stream API 提供的一个方法,用于过滤 Stream 中的元素,它是在 Stream 中使用的。在 Stream 中使用 filter 方法时,可以通过 Lambda 表达式定义一个过滤条件,只有符合该条件的元素才会被保留下来,而不符合条件的元素会被过滤掉。例如,假设有一个名为 list
的 List,其中包含一些整数,如果要将其中大于 10 的整数筛选出来,可以使用以下代码:
List<Integer> filteredList = list.stream()
.filter(i -> i > 10)
.collect(Collectors.toList());
上面的代码中,list.stream()
将 List 转换成一个 Stream,然后使用 filter 方法过滤掉不符合条件的元素,只保留大于 10 的整数。最后使用 collect 方法将符合条件的元素转换成一个 List。
需要注意的是,filter 方法并不会修改原始的 Stream,而是生成一个新的 Stream,因此可以在多个操作中连续使用 filter 方法。
2.Stream API 提供了一个 map 方法,用于将一个 Stream 中的元素进行映射转换。map 方法会对 Stream 中的每个元素应用一个函数,返回一个新的 Stream,该 Stream 中的元素是映射后的结果。
map 方法的使用方式如下:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream()
.map(n -> n * n)
.collect(Collectors.toList());
上面的代码中,首先创建了一个 List,然后使用 stream 方法将其转换成一个 Stream。接着使用 map 方法将 Stream 中的每个元素进行平方映射,并返回一个新的 Stream。最后使用 collect 方法将新的 Stream 转换成一个 List,并将结果赋值给 result 变量。
需要注意的是,map 方法并不会修改原始的 Stream,而是生成一个新的 Stream,因此可以在多个操作中连续使用 map 方法。
除了使用 Lambda 表达式,还可以使用方法引用来定义 map 方法的函数,例如:
List<String> list = Arrays.asList("apple", "banana", "orange");
List<Integer> result = list.stream()
.map(String::length)
.collect(Collectors.toList());
上面的代码中,使用方法引用将 String 类型的元素转换为 Integer 类型的元素,返回了一个新的 Stream。
3.Stream API 提供了一个 reduce 方法,用于将 Stream 中的元素进行归约操作。reduce 方法接受一个 BinaryOperator 函数作为参数,该函数用于将 Stream 中的元素两两结合,得到一个新的结果,然后将该结果再与下一个元素结合,以此类推,最终得到一个归约后的结果。
reduce 方法的使用方式如下:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream().reduce(0, (a, b) -> a + b);
上面的代码中,首先创建了一个 List,然后使用 stream 方法将其转换成一个 Stream。接着使用 reduce 方法将 Stream 中的所有元素相加,并返回结果。reduce 方法接受两个参数,第一个参数是初始值,第二个参数是一个 BinaryOperator 函数,用于将 Stream 中的元素两两结合。
在上面的例子中,初始值为 0,然后将每个元素与上一个结果相加,得到最终的归约结果。
需要注意的是,reduce 方法会返回一个 Optional 对象,该对象可能为空,因此需要进行判断或者使用 orElse 方法提供一个默认值。例如:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream().reduce(0, (a, b) -> a + b);
int product = list.stream().reduce(1, (a, b) -> a * b);
int max = list.stream().reduce(0, Integer::max);
int min = list.stream().reduce(Integer.MAX_VALUE, Integer::min);
上面的代码中,分别计算了 Stream 中的元素的和、积、最大值和最小值,并返回结果。需要注意的是,在计算最大值和最小值时,初始值需要设置成 Integer.MAX_VALUE 和 Integer.MIN_VALUE。
4.groupingBy:
Stream API 提供了一个 Collectors 工具类,其中包含了许多用于 Stream 的归约操作的方法,其中之一就是 groupingBy 方法。groupingBy 方法用于按照某个属性对 Stream 中的元素进行分组,并将分组后的元素放入一个 Map 中。
groupingBy 方法的使用方式如下:
List<Person> persons = Arrays.asList(
new Person("Alice", "London"),
new Person("Bob", "New York"),
new Person("Charlie", "London"),
new Person("David", "New York")
);
Map<String, List<Person>> result = persons.stream()
.collect(Collectors.groupingBy(Person::getCity));
上面的代码中,首先创建了一个 List,其中包含了一些 Person 对象。接着使用 stream 方法将其转换成一个 Stream。然后使用 Collectors.groupingBy 方法按照城市对 Person 对象进行分组,并将分组后的结果放入一个 Map 中。在分组时,可以通过方法引用指定分组的属性,例如上面的代码中使用 Person::getCity
指定按照城市进行分组。
需要注意的是,groupingBy 方法返回的 Map 中的键是分组的属性值,值是对应属性值的元素列表。
除了按照一个属性进行分组外,还可以使用多个属性进行分组。例如,假设 Person 类中有两个属性,分别为 name 和 city,可以使用以下代码按照两个属性进行分组:
Map<String, Map<String, List<Person>>> result = persons.stream()
.collect(Collectors.groupingBy(Person::getCity, Collectors.groupingBy(Person::getName)));
上面的代码中,首先按照城市进行分组,然后按照姓名进行分组,并将分组后的结果放入一个嵌套的 Map 中。
总之,groupingBy 方法是 Collectors 工具类中提供的一个方法,用于按照某个属性对 Stream 中的元素进行分组,并将分组后的元素放入一个 Map 中。在分组时,可以通过方法引用指定分组的属性。除了按照一个属性进行分组外,还可以使用多个属性进行分组,并将分组后的结果放入一个嵌套的 Map 中。
5.toMap :
toMap 方法用于将 Stream 中的元素转换成一个 Map,其中键值对由一个属性的值和另一个属性的值组成。
toMap 方法的使用方式如下:
List<Person> persons = Arrays.asList(
new Person("Alice", "London"),
new Person("Bob", "New York"),
new Person("Charlie", "London"),
new Person("David", "New York")
);
Map<String, String> result = persons.stream()
.collect(Collectors.toMap(Person::getName, Person::getCity));
上面的代码中,首先创建了一个 List,其中包含了一些 Person 对象。接着使用 stream 方法将其转换成一个 Stream。然后使用 Collectors.toMap 方法将 Stream 中的元素转换成一个 Map。在转换时,可以通过方法引用指定 Map 中的键和值,例如上面的代码中使用 Person::getName
指定 Map 的键,使用 Person::getCity
指定 Map 的值。
需要注意的是,如果 Stream 中存在相同的键,则会抛出 IllegalStateException 异常。为了解决这个问题,可以使用 toMap 方法的重载版本,并指定合并函数,例如:
List<Person> persons = Arrays.asList(
new Person("Alice", "London"),
new Person("Bob", "New York"),
new Person("Charlie", "London"),
new Person("David", "New York")
);
Map<String, String> result = persons.stream()
.collect(Collectors.toMap(Person::getName, Person::getCity, (a, b) -> a + "," + b));
上面的代码中,使用 a + "," + b
指定了合并函数,当存在相同的键时,将其对应的值合并成一个字符串,并用逗号隔开。
除了将两个属性转换成键值对外,toMap 方法还支持将一个属性作为键,将整个对象作为值,例如:
Map<String, Person> result = persons.stream()
.collect(Collectors.toMap(Person::getName, Function.identity()));
上面的代码中,使用 Function.identity()
指定将整个对象作为值。