將一個對象的集合轉化成另外一個對象的集合 https://send.firefox.com/download/8a176f99db42673a/#M1frI1Q8OAo8bZVVcb1oKQhtml
List<OrderDetail> orderDetailList = orderDetailService.listOrderDetails(); List<CartDTO> cartDTOList = orderDetailList.stream() .map(e -> new CartDTO(e.getProductId(), e.getProductQuantity())) .collect(Collectors.toList());
交集 (list1 + list2)java
List<T> intersect = list1.stream()
.filter(list2::contains)
.collect(Collectors.toList());
差集app
//(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());
並集函數
//使用並行流 List<String> listAll = list1.parallelStream().collect(toList()); List<String> listAll2 = list2.parallelStream().collect(toList()); listAll.addAll(listAll2);
去重並集spa
List<String> listAllDistinct = listAll.stream() .distinct().collect(Collectors.toList());
從List中過濾出一個元素.net
User match = users.stream()
.filter((user) -> user.getId() == 1).findAny().get();
Map集合轉 Listfirefox
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集合轉 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>code
/** * 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>>orm
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 爲對象 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); });
字典查詢和數據轉換 toMap時,若是value爲null,會報空指針異常
//方法一 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()); }
假設有一個User實體類,有方法getId(),getName(),getAge()等方法,如今想要將User類型的流收集到一個Map中,示例以下:
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 轉 另外一個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 根據年齡來分組:
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分別提供了求平均值averaging、總數couting、最小值minBy、最大值maxBy、求和suming等操做。可是假如你但願將流中結果聚合爲一個總和、平均值、最大值、最小值,那麼Collectors.summarizing(Int/Long/Double)就是爲你準備的,它能夠一次行獲取前面的全部結果,其返回值爲(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}
使用collect能夠將Stream轉換成值。maxBy和minBy容許用戶按照某個特定的順序生成一個值。
averagingDouble:求平均值,Stream的元素類型爲double
averagingInt:求平均值,Stream的元素類型爲int
averagingLong:求平均值,Stream的元素類型爲long
counting:Stream的元素個數
maxBy:在指定條件下的,Stream的最大元素
minBy:在指定條件下的,Stream的最小元素
reducing: reduce操做
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