1.List转Map
// key为某属性,value为某属性
Map<Integer, String> idNameMap = userList.stream().collect(Collectors.toMap(User::getId, User::getName));
System.out.println("idNameMap = " + idNameMap);
// key为某属性,value为对象本身(方法1)
Map<Integer, User> idUserMap1 = userList.stream().collect(Collectors.toMap(User::getId, user -> user));
System.out.println("idUserMap1 = " + idUserMap1);
// key为某属性,value为对象本身(方法2)
Map<Integer, User> idUserMap2 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
System.out.println("idUserMap2 = " + idUserMap2);
Map<String,Object> map = list.stream().collect(Collectors.toMap(Map -> Map.get("id"), id -> id));
key值冲突问题:
// key值冲突解决(后面的覆盖前面的)
Map<Integer, User> idUserMap = userList.stream().collect(Collectors.toMap(User::getId, user -> user, (key1, key2) -> key2));
System.out.println("idUserMap = " + idUserMap);
// key值冲突解决(自定义业务逻辑)
Map<Integer, User> idUserMap = userList.stream().collect(Collectors.toMap(User::getId, user -> user, (user1, user2) -> {
// 根据自己的业务逻辑,返回一个User对象即可
// 比如这里返回age较大的一个User
return (user1.getAge() > user2.getAge()) ? user1 : user2;
}));
System.out.println("idUserMap = " + idUserMap);
2.将list中所有对象的某个属性提取出来作为一个新的list
List<String> idList = list.stream().map(Map -> Map.get("id")).collect(Collectors.toList());
3.Java的Stream流,groupingBy之后无序解决办法
可以直接使用含三个参数的函数,传入有顺序的Map,LinkedHashMap,这样分组之后的顺序就是原来List集合的数据。
groupingBy(User::getAge(), LinkedHashMap::new, Collectors.toList())
4.
Java Stream流对集合进行分组操作
Java Stream流提供了groupingBy()
方法,可以对集合进行分组操作。groupingBy()
方法接受一个Function
参数,用于指定分组的条件,并返回一个Collector
对象,用于执行分组操作。
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GroupingExample {
public static void main(String[] args) {
// 创建一个包含学生对象的集合
List<Student> students = Arrays.asList(
new Student("John", "Math"),
new Student("Alice", "Science"),
new Student("Bob", "Math"),
new Student("Charlie", "Science"),
new Student("David", "Math")
);
// 使用Stream流对学生集合进行专业(course)分组
Map<String, List<Student>> groupedByCourse = students.stream()
.collect(Collectors.groupingBy(Student::getCourse));
// 打印分组结果
for (Map.Entry<String, List<Student>> entry : groupedByCourse.entrySet()) {
String course = entry.getKey();
List<Student> studentsInCourse = entry.getValue();
System.out.println("Course: " + course);
for (Student student : studentsInCourse) {
System.out.println("- " + student.getName());
}
System.out.println();
}
}
}
class Student {
private String name;
private String course;
public Student(String name, String course) {
this.name = name;
this.course = course;
}
public String getName() {
return name;
}
public String getCourse() {
return course;
}
}
运行结果:
Course: Math
- John
- Bob
- David
Course: Science
- Alice
- Charlie
在示例中,我们创建了一个包含学生对象的集合students。然后,我们使用stream()方法将集合转换为Stream流,并使用groupingBy()方法对学生集合进行分组,按照学生的专业(course)进行分组。分组结果存储在一个Map<String, List<Student>>对象中,其中键是专业名,值是对应专业的学生列表。
5.分组的使用
分组:
package com.mkyong.java8;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Java8Example1 {
public static void main(String[] args) {
//3 apple, 2 banana, others 1
List<String> items =
Arrays.asList("apple", "apple", "banana",
"apple", "orange", "banana", "papaya");
Map<String, Long> result =
items.stream().collect(
Collectors.groupingBy(
Function.identity(), Collectors.counting()
)
);
System.out.println(result);
}
}
运行结果:
{
papaya=1, orange=1, banana=2, apple=3
}
排序:
package com.mkyong.java8;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Java8Example2 {
public static void main(String[] args) {
//3 apple, 2 banana, others 1
List<String> items =
Arrays.asList("apple", "apple", "banana",
"apple", "orange", "banana", "papaya");
Map<String, Long> result =
items.stream().collect(
Collectors.groupingBy(
Function.identity(), Collectors.counting()
)
);
Map<String, Long> finalMap = new LinkedHashMap<>();
//Sort a map and add to finalMap
result.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue()
.reversed()).forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));
System.out.println(finalMap);
}
}
运行结果:
{
apple=3, banana=2, papaya=1, orange=1
}
用户定义的对象排序:
package com.mkyong.java8;
import java.math.BigDecimal;
public class Item {
private String name;
private int qty;
private BigDecimal price;
//constructors, getter/setters
}
package com.mkyong.java8;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Java8Examples3 {
public static void main(String[] args) {
//3 apple, 2 banana, others 1
List<Item> items = Arrays.asList(
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 20, new BigDecimal("19.99")),
new Item("orang", 10, new BigDecimal("29.99")),
new Item("watermelon", 10, new BigDecimal("29.99")),
new Item("papaya", 20, new BigDecimal("9.99")),
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 10, new BigDecimal("19.99")),
new Item("apple", 20, new BigDecimal("9.99"))
);
Map<String, Long> counting = items.stream().collect(
Collectors.groupingBy(Item::getName, Collectors.counting()));
System.out.println(counting);
Map<String, Integer> sum = items.stream().collect(
Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));
System.out.println(sum);
}
}
运行结果:
//Group by + Count
{
papaya=1, banana=2, apple=3, orang=1, watermelon=1
}
//Group by + Sum qty
{
papaya=20, banana=30, apple=40, orang=10, watermelon=10
}
package com.mkyong.java8;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class Java8Examples4 {
public static void main(String[] args) {
//3 apple, 2 banana, others 1
List<Item> items = Arrays.asList(
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 20, new BigDecimal("19.99")),
new Item("orang", 10, new BigDecimal("29.99")),
new Item("watermelon", 10, new BigDecimal("29.99")),
new Item("papaya", 20, new BigDecimal("9.99")),
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 10, new BigDecimal("19.99")),
new Item("apple", 20, new BigDecimal("9.99"))
);
//group by price
Map<BigDecimal, List<Item>> groupByPriceMap =
items.stream().collect(Collectors.groupingBy(Item::getPrice));
System.out.println(groupByPriceMap);
// group by price, uses 'mapping' to convert List<Item> to Set<String>
Map<BigDecimal, Set<String>> result =
items.stream().collect(
Collectors.groupingBy(Item::getPrice,
Collectors.mapping(Item::getName, Collectors.toSet())
)
);
System.out.println(result);
}
}
运行结果:
{
19.99=[
Item{name='banana', qty=20, price=19.99},
Item{name='banana', qty=10, price=19.99}
],
29.99=[
Item{name='orang', qty=10, price=29.99},
Item{name='watermelon', qty=10, price=29.99}
],
9.99=[
Item{name='apple', qty=10, price=9.99},
Item{name='papaya', qty=20, price=9.99},
Item{name='apple', qty=10, price=9.99},
Item{name='apple', qty=20, price=9.99}
]
}
//group by + mapping to Set
{
19.99=[banana],
29.99=[orang, watermelon],
9.99=[papaya, apple]
}
二次排序:
List<Something> sorted=somethings.stream().sorted(
Comparator.comparing((Something x)->totalNoThings.get(x.getParentKey()))
.thenComparing(Something::getNoThings).reversed())
.collect(Collectors.toList());
多条件分组:
Map<List<String>, Integer> map =
myList.stream()
.collect(Collectors.groupingBy(
f -> Arrays.asList(f.getType(), f.getCode()),
Collectors.summingInt(Foo::getQuantity)
));
List<Foo> result =
map.entrySet()
.stream()
.map(e -> new Foo(e.getKey().get(0), e.getValue(), e.getKey().get(1)))
.collect(Collectors.toList());
高级写法:
List<Foo> result = new ArrayList<>(
myList.stream()
.collect(Collectors.groupingBy(
f -> Arrays.<String>asList(f.getType(), f.getCode()),
MoreCollectors.pairing(
Collectors.collectingAndThen(MoreCollectors.first(), Optional::get),
Collectors.summingInt(Foo::getQuantity),
(f, s) -> new Foo(f.getType(), s, f.getCode())
)
)).values());
Map<Department, Integer> totalByDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.summingInt(Employee::getSalary)));
整理收集自:
Java Stream常见操作_stream map取value某字段-CSDN博客
Java的Stream流,groupingBy之后无序解决办法_stream().groupby方法后 列表乱序-CSDN博客