java8 .stream().collect() routine business use api

Table of contents

steam()

forEach()

map()

filter()

sorted():

intersection(list1 + list2)

difference set

union

deduplication union

Map collection to List

List collection to Map

List to Map,apple>

Collectors toList

map value is the object student

Map to another Map

Collectors toSet

Collectors groupingBy

groupingBy groups by age:

reducing: reduce operation


demo:

API: https://www.runoob.com/java/java8-streams.html

mylist.stream()
    .map(myfunction->{
        return item;
    }).collect(Collectors.toList());

illustrate:


steam()

: Convert a source data, which can be a collection, an array, an I/O channel, a generator, etc., into a stream.

forEach()

: Iterate over each data in the stream. The following code snippet uses forEach to output 10 random numbers.

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

map()

: Used to map each element to the corresponding result. The following code snippet uses map to output the square number corresponding to the element:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

filter()

The :filter method is used to filter out elements by setting conditions. The following code snippet uses the filter method to filter out empty strings:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
int count = strings.stream().filter(string -> string.isEmpty()).count();
limit
limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

sorted():

Used to sort streams. The following code snippet uses the sorted method to sort the output of 10 random numbers:

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
并行(parallel)程序
parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
int count = strings.parallelStream().filter(string -> string.isEmpty()).count();

We can easily switch between running sequentially and running in parallel.

Collectors(): The class implements many reduction operations, such as converting streams into collections and aggregating elements. Collectors can be used to return lists or strings:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);

Transforms a collection of objects into another collection of objects

List<OrderDetail> orderDetailList = orderDetailService.listOrderDetails();
List<CartDTO> cartDTOList = orderDetailList.stream()
                .map(e -> new CartDTO(e.getProductId(), e.getProductQuantity()))
                .collect(Collectors.toList());

intersection(list1 + list2)

List<T> intersect = list1.stream()
                         .filter(list2::contains)
                         .collect(Collectors.toList());

difference set

//(list1 - list2)
List<String> reduce1 = list1.stream().filter(item -> !list2.contains(item)).collect(toList());


//(list2 - list1)
List<String> reduce2 = list2.stream().filter(item -> !list1.contains(item)).collect(toList());

union

//使用并行流 
List<String> listAll = list1.parallelStream().collect(toList());
List<String> listAll2 = list2.parallelStream().collect(toList());
listAll.addAll(listAll2);

deduplication union

List<String> listAllDistinct = listAll.stream()
.distinct().collect(Collectors.toList());
从List中过滤出一个元素
User match = users.stream()
.filter((user) -> user.getId() == 1).findAny().get();

Map collection to List

List<Person> list = map.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey()))
        .map(e -> new Person(e.getKey(), e.getValue())).collect(Collectors.toList());
        
List<Person> list = map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue)).map(e -> new Person(e.getKey(), e.getValue())).collect(Collectors.toList());

List<Person> list = map.entrySet().stream().sorted(Map.Entry.comparingByKey()).map(e -> new Person(e.getKey(), e.getValue())).collect(Collectors.toList());

List collection to Map

/*使用Collectors.toMap形式*/
Map result = peopleList.stream().collect(Collectors.toMap(p -> p.name, p -> p.age, (k1, k2) -> k1));
//其中Collectors.toMap方法的第三个参数为键值重复处理策略,如果不传入第三个参数,当有相同的键时,会抛出一个IlleageStateException。
//或者
Map<Integer, String> result1 = list.stream().collect(Collectors.toMap(Hosting::getId, Hosting::getName));
//List<People> -> Map<String,Object>
List<People> peopleList = new ArrayList<>();
peopleList.add(new People("test1", "111"));
peopleList.add(new People("test2", "222"));
Map result = peopleList.stream().collect(HashMap::new,(map,p)->map.put(p.name,p.age),Map::putAll);

List 转 Map<Integer,Apple>

/**
 * List<Apple> -> Map<Integer,Apple>
 * 需要注意的是:
 * toMap 如果集合对象有重复的key,会报错Duplicate key ....
 *  apple1,apple12的id都为1。
 *  可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
 */
Map<Integer, Apple> appleMap = appleList.stream().collect(Collectors.toMap(Apple::getId, a -> a,(k1, k2) -> k1));
复制代码
List 转 List<Map<String,Object>>

List<Map<String,Object>> personToMap = peopleList.stream().map((p) -> {
    Map<String, Object> map = new HashMap<>();
    map.put("name", p.name);
    map.put("age", p.age);
    return map;
}).collect(Collectors.toList());
//或者
List<Map<String,Object>> personToMap = peopleList.stream().collect(ArrayList::new, (list, p) -> {
   Map<String, Object> map = new HashMap<>();
    map.put("name", p.name);
    map.put("age", p.age);
    list.add(map);
}, List::addAll);

Collectors toList

streamArr.collect(Collectors.toList());
List<Integer> collectList = Stream.of(1, 2, 3, 4)
        .collect(Collectors.toList());
System.out.println("collectList: " + collectList);
// 打印结果 collectList: [1, 2, 3, 4]
Collectors toMap

map value is the object student

Map<Integer, Student> map = list.stream().collect(Collectors.toMap(Student::getId, student -> student));
// 遍历打印结果
map.forEach((key, value) -> {
    System.out.println("key: " + key + "    value: " + value);
});
map value 为对象中的属性
Map<Integer, String> map = list.stream().collect(Collectors.toMap(Student::getId, Student::getName));
map.forEach((key, value) -> {
    System.out.println("key: " + key + "    value: " + value);
});

During dictionary query and data conversion toMap, if the value is null, a null pointer exception will be reported

 
 

//方法一
Map<String, List<Dict>> resultMaps = Arrays.stream(dictTypes)
.collect(Collectors.toMap(i -> i, i -> Optional.ofNullable(dictMap.get(i)).orElse(new ArrayList<>()), (k1, k2) -> k2));
//方法二
Map<String, List<Dict>> resultMaps = Arrays.stream(dictTypes)
.filter(i -> dictMap.get(i) != null).collect(Collectors.toMap(i -> i, dictMap::get, (k1, k2) -> k2));

//方法三
Map<String, String> memberMap = list.stream().collect(HashMap::new, (m,v)->
    m.put(v.getId(), v.getImgPath()),HashMap::putAll);
System.out.println(memberMap);
//方法四
Map<String, String> memberMap = new HashMap<>();
list.forEach((answer) -> memberMap.put(answer.getId(), answer.getImgPath()));
System.out.println(memberMap);

Map<String, String> memberMap = new HashMap<>();
for (Member member : list) {
    memberMap.put(member.getId(), member.getImgPath());
}

Suppose there is a User entity class with methods such as getId(), getName(), getAge(), etc. Now you want to collect the flow of User type into a Map. The example is as follows:

Stream<User> userStream = Stream.of(new User(0, "张三", 18), new User(1, "张四", 19), new User(2, "张五", 19), new User(3, "老张", 50));

Map<Integer, User> userMap = userSteam.collect(Collectors.toMap(User::getId, item -> item));
假设要得到按年龄分组的Map<Integer,List>,可以按这样写:


Map<Integer, List<User>> ageMap = userStream.collect(Collectors.toMap(User::getAge, Collections::singletonList, (a, b) -> {
            List<User> resultList = new ArrayList<>(a);
            resultList.addAll(b);
            return resultList;
        }));

Map<Integer, String> map = persons
    .stream()
    .collect(Collectors.toMap(
        p -> p.age,
        p -> p.name,
        (name1, name2) -> name1 + ";" + name2));

System.out.println(map);
// {18=Max, 23=Peter;Pamela, 12=David}

Map to another Map

//示例1 Map<String, List<String>> 转 Map<String,User>
Map<String,List<String>> map = new HashMap<>();
map.put("java", Arrays.asList("1.7", "1.8"));
map.entrySet().stream();

@Getter
@Setter
@AllArgsConstructor
public static class User{
    private List<String> versions;
}

Map<String, User> collect = map.entrySet().stream()
                .collect(Collectors.toMap(
                        item -> item.getKey(),
                        item -> new User(item.getValue())));

//示例2 Map<String,Integer>  转 Map<String,Double>
Map<String, Integer> pointsByName = new HashMap<>();
Map<String, Integer> maxPointsByName = new HashMap<>();

Map<String, Double> gradesByName = pointsByName.entrySet().stream()
        .map(entry -> new AbstractMap.SimpleImmutableEntry<>(
                entry.getKey(), ((double) entry.getValue() /
                        maxPointsByName.get(entry.getKey())) * 100d))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Collectors toSet

Set<String> result = Stream.of("aa", "bb", "cc", "aa").collect(HashSet::new, HashSet::add, HashSet::addAll);
//Collectors类中已经预定义好了toList,toSet,toMap,toCollection等方便使用的方法,所以以上代码还可以简化如下:
Set<String> result2 = Stream.of("aa", "bb", "cc", "aa").collect(Collectors.toSet());

Set<Integer> collectSet = Stream.of(1, 2, 3, 4).collect(Collectors.toSet());
System.out.println("collectSet: " + collectSet);
// 打印结果 collectSet: [1, 2, 3, 4]

Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));
// collect toString
String str = stream.collect(Collectors.joining()).toString();

Collectors groupingBy

Map<Integer, List<User>> ageMap2 = userStream
.collect(Collectors.groupingBy(User::getAge));
//groupingBy 分组后操作
//Collectors中还提供了一些对分组后的元素进行downStream处理的方法:
//counting方法返回所收集元素的总数;
//summing方法会对元素求和;
//maxBy和minBy会接受一个比较器,求最大值,最小值;
//mapping函数会应用到downstream结果上,并需要和其他函数配合使用;

Map<Integer, Long> sexCount = userStream.collect(Collectors.groupingBy(User::getSex,Collectors.counting()));

Map<Integer, Integer> ageCount = userStream.collect(Collectors.groupingBy(User::getSex,Collectors.summingInt(User::getAge)));

Map<Integer, Optional<User>> ageMax =  userStream.collect(Collectors.groupingBy(User::getSex,Collectors.maxBy(Comparator.comparing(User::getAge))));

Map<Integer, List<String>> nameMap =  userStream.collect(Collectors.groupingBy(User::getSex,Collectors.mapping(User::getName,Collectors.toList())));

groupingBy groups by age:

Map<Integer, List> peopleByAge = peoples.stream()
.filter(p -> p.age > 12).collect(Collectors.groupingBy(p -> p.age, Collectors.toList()));
groupingBy 根据年龄分组,年龄对应的键值List存储的为Person的姓名:

Map<Integer, List> peopleByAge = people.stream()
.collect(Collectors.groupingBy(p -> p.age, Collectors.mapping((Person p) -> p.name, Collectors.toList())));
//mapping即为对各组进行投影操作,和Stream的map方法基本一致。
groupingBy 根据姓名分组,获取每个姓名下人的年龄总和:

Map sumAgeByName = peoples.stream().collect(Collectors.groupingBy(p -> p.name, Collectors.reducing(0, (Person p) -> p.age, Integer::sum)));
/* 或者使用summingInt方法 */
sumAgeByName = peoples.stream().collect(Collectors.groupingBy(p -> p.name, Collectors.summingInt((Person p) -> p.age)));
groupingBy Boolean分组:

Map<Boolean, List<Integer>> collectGroup = Stream.of(1, 2, 3, 4)
            .collect(Collectors.groupingBy(it -> it > 3));
System.out.println("collectGroup : " + collectGroup);
// 打印结果
// collectGroup : {false=[1, 2, 3], true=[4]}
groupingBy 按年龄分组

Map<Integer, List<Person>> personsByAge = persons.stream().collect(Collectors.groupingBy(p -> p.age));
personsByAge.forEach((age, p) -> System.out.format("age %s: %s\n", age, p));
// age 18: [Max]
// age 23: [Peter, Pamela]
// age 12: [David]
Collectors partitioningBy
Collectors中还提供了partitioningBy方法,接受一个Predicate函数,该函数返回boolean值,用于将内容分为两组。假设User实体中包含性别信息getSex(),可以按如下写法将userStream按性别分组:

Map<Boolean, List<User>> sexMap = userStream
.collect(Collectors.partitioningBy(item -> item.getSex() > 0));
可以看到Java8的分组功能相当强大,当然你还可以完成更复杂的功能。另外Collectors中还存在一个类似groupingBy的方法:partitioningBy,它们的区别是partitioningBy为键值为Boolean类型的groupingBy,这种情况下它比groupingBy更有效率。

partitioningBy 将数字的Stream分解成奇数集合和偶数集合。

Map<Boolean, List<Integer>> collectParti = Stream.of(1, 2, 3, 4)
            .collect(Collectors.partitioningBy(it -> it % 2 == 0));
System.out.println("collectParti : " + collectParti);
// 打印结果
// collectParti : {false=[1, 3], true=[2, 4]}
Collectors joining
Collectors.joining 收集Stream中的值,该方法可以方便地将Stream得到一个字符串。joining函数接受三个参数,分别表示允(用以分隔元素)、前缀和后缀:
String names = peoples.stream().map(p->p.name).collect(Collectors.joining(","))

String strJoin = Stream.of("1", "2", "3", "4")
        .collect(Collectors.joining(",", "[", "]"));
System.out.println("strJoin: " + strJoin);
// 打印结果
// strJoin: [1,2,3,4]

//字符串连接
String phrase = persons
    .stream()
    .filter(p -> p.age >= 18)
    .map(p -> p.name)
    .collect(Collectors.joining(" and ", "In Germany ", " are of legal age."));
System.out.println(phrase);
// In Germany Max and Peter and Pamela are of legal age.

Collectors provide operations such as averaging, total counting, minimum minBy, maximum maxBy, summing, etc. But if you want to aggregate the results in the stream into a sum, average, maximum value, minimum value, then Collectors.summarizing(Int/Long/Double) is for you, it can get all the previous results in one row, other The return value is (Int/Long/Double)SummaryStatistics.


 

DoubleSummaryStatistics dss = people.collect(Collectors.summarizingDouble((Person p)->p.age));
double average=dss.getAverage();
double max=dss.getMax();
double min=dss.getMin();
double sum=dss.getSum();
double count=dss.getCount();

IntSummaryStatistics ageSummary = persons
        .stream()
        .collect(Collectors.summarizingInt(p -> p.age));

System.out.println(ageSummary);
// IntSummaryStatistics{count=4, sum=76, min=12, average=19.000000, max=23}

Use collect to convert the Stream into a value. maxBy and minBy allow the user to generate a value in a specific order.

averagingDouble: average, the element type of Stream is double

averagingInt: average value, the element type of Stream is int

averagingLong: average value, the element type of Stream is long

counting: the number of elements of Stream

maxBy: Under the specified conditions, the largest element of Stream

minBy: Under the specified conditions, the smallest element of Stream

reducing: reduce operation

summarizingDouble:统计Stream的数据(double)状态,其中包括count,min,max,sum和平均。

summarizingInt:统计Stream的数据(int)状态,其中包括count,min,max,sum和平均。

summarizingLong:统计Stream的数据(long)状态,其中包括count,min,max,sum和平均。

summingDouble:求和,Stream的元素类型为double

summingInt:求和,Stream的元素类型为int

summingLong:求和,Stream的元素类型为long



Optional<Integer> collectMaxBy = Stream.of(1, 2, 3, 4)
            .collect(Collectors.maxBy(Comparator.comparingInt(o -> o)));
System.out.println("collectMaxBy:" + collectMaxBy.get());
// 打印结果
// collectMaxBy:4
Collectors averagingInt计算平均值

Double averageAge = persons
    .stream()
    .collect(Collectors.averagingInt(p -> p.age));

System.out.println(averageAge);     // 19.0

Reference link: Usage of java8 .stream().map().collect()_localhost-9527's Blog-CSDN Blog

Guess you like

Origin blog.csdn.net/qq_44691484/article/details/129369838