例1:
1 public class GroupBy { 2 3 List<Employee> employees = new ArrayList<>(); 4 5 /** 6 * 數據初始化 7 */ 8 public void init() { 9 List<String> citys = Arrays.asList("湖南", "湖北", "四川", "廣東 "); 10 for (int i = 0; i < 10; i++) { 11 Random random = new Random(); 12 Integer index = random.nextInt(4); 13 Employee employee = new Employee(citys.get(index), "姓名" + i, (random.nextInt(4) * 10 - random.nextInt(4)), 14 (random.nextInt(4) * 1000 - random.nextInt(4))); 15 employees.add(employee); 16 } 17 } 18 19 /** 20 * 使用java8 stream groupingBy操作,按城市分組list 21 */ 22 public void groupingByCity() { 23 Map<String, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity)); 24 25 map.forEach((k, v) -> System.out.println(k + " = " + v)); 26 //四川 = [GroupBy.Employee(city=四川, name=姓名1, age=30, amount=999), GroupBy.Employee(city=四川, name=姓名2, age=8, amount=2000), GroupBy.Employee(city=四川, name=姓名3, age=30, amount=2997)] 27 //湖南 = [GroupBy.Employee(city=湖南, name=姓名7, age=30, amount=-3), GroupBy.Employee(city=湖南, name=姓名8, age=19, amount=1998)] 28 //湖北 = [GroupBy.Employee(city=湖北, name=姓名4, age=29, amount=-2), GroupBy.Employee(city=湖北, name=姓名5, age=10, amount=1997)] 29 //廣東 = [GroupBy.Employee(city=廣東 , name=姓名0, age=28, amount=1998), GroupBy.Employee(city=廣東 , name=姓名6, age=29, amount=1998), GroupBy.Employee(city=廣東 , name=姓名9, age=7, amount=1000)] 30 } 31 32 /** 33 * 使用java8 stream groupingBy操作,按城市分組list統計count 34 */ 35 public void groupingByCount() { 36 Map<String, Long> map = employees.stream() 37 .collect(Collectors.groupingBy(Employee::getCity, Collectors.counting())); 38 39 map.forEach((k, v) -> System.out.println(k + " = " + v)); 40 //四川 = 1 41 //湖北 = 3 42 //湖南 = 4 43 //廣東 = 2 44 } 45 46 /** 47 * 使用java8 stream groupingBy操作,按城市分組list並計算分組年齡平均值 48 */ 49 public void groupingByAverage() { 50 Map<String, Double> map = employees.stream() 51 .collect(Collectors.groupingBy(Employee::getCity, Collectors.averagingInt(Employee::getAge))); 52 53 map.forEach((k, v) -> System.out.println(k + " = " + v)); 54 //四川 = 15.0 55 //湖北 = 21.25 56 //湖南 = 18.333333333333332 57 //廣東 = 9.0 58 } 59 60 /** 61 * 使用java8 stream groupingBy操作,按城市分組list並計算分組銷售總值 62 */ 63 public void groupingBySum() { 64 Map<String, Long> map = employees.stream() 65 .collect(Collectors.groupingBy(Employee::getCity, Collectors.summingLong(Employee::getAmount))); 66 67 map.forEach((k, v) -> System.out.println(k + " = " + v)); 68 //四川 = 3995 69 //湖北 = 2995 70 //湖南 = 999 71 //廣東 = 8994 72 73 // 對Map按照分組銷售總值逆序排序 74 Map<String, Long> sortedMap = new LinkedHashMap<>(); 75 map.entrySet().stream().sorted(Map.Entry.<String, Long> comparingByValue().reversed()) 76 .forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue())); 77 78 sortedMap.forEach((k, v) -> System.out.println(k + " = " + v)); 79 //廣東 = 8994 80 //四川 = 3995 81 //湖北 = 2995 82 //湖南 = 999 83 } 84 85 86 /** 87 * 使用java8 stream groupingBy操作,按城市分組list並通過join操作連接分組list中的對象的name 屬性使用逗號分隔 88 */ 89 public void groupingByString() { 90 Map<String, String> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity, 91 Collectors.mapping(Employee::getName, Collectors.joining(", ", "Names: [", "]")))); 92 93 map.forEach((k, v) -> System.out.println(k + " = " + v)); 94 //四川 = Names: [姓名8] 95 //湖南 = Names: [姓名1, 姓名2, 姓名7] 96 //湖北 = Names: [姓名0, 姓名3, 姓名6, 姓名9] 97 //廣東 = Names: [姓名4, 姓名5] 98 } 99 100 /** 101 * 使用java8 stream groupingBy操作,按城市分組list,將List轉化為name的List 102 */ 103 public void groupingByList() { 104 Map<String, List<String>> map = employees.stream().collect( 105 Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toList()))); 106 107 map.forEach((k, v) -> { 108 System.out.println(k + " = " + v); 109 v.forEach(item -> System.out.println("item = " + item)); 110 }); 111 //四川 = [姓名6] 112 //item = 姓名6 113 //湖北 = [姓名2, 姓名5, 姓名7] 114 //item = 姓名2 115 //item = 姓名5 116 //item = 姓名7 117 //湖南 = [姓名0, 姓名1, 姓名3, 姓名4] 118 //item = 姓名0 119 //item = 姓名1 120 //item = 姓名3 121 //item = 姓名4 122 //廣東 = [姓名8, 姓名9] 123 //item = 姓名8 124 //item = 姓名9 125 } 126 127 /** 128 * 使用java8 stream groupingBy操作,按城市分組list,將List轉化為name的Set 129 */ 130 public void groupingBySet() { 131 Map<String, Set<String>> map = employees.stream().collect( 132 Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toSet()))); 133 134 map.forEach((k, v) -> { 135 System.out.println(k + " = " + v); 136 v.forEach(item -> System.out.println("item = " + item)); 137 }); 138 } 139 140 /** 141 * 使用java8 stream groupingBy操作,通過Object對象的成員分組List 142 */ 143 public void groupingByObject() { 144 Map<Manage, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(item -> new Manage(item.getName()))); 145 146 map.forEach((k, v) -> System.out.println(k + " = " + v)); 147 //GroupBy.Manage(name=姓名9) = [GroupBy.Employee(city=廣東 , name=姓名9, age=19, amount=2998)] 148 //GroupBy.Manage(name=姓名8) = [GroupBy.Employee(city=四川, name=姓名8, age=-2, amount=3000)] 149 //GroupBy.Manage(name=姓名7) = [GroupBy.Employee(city=廣東 , name=姓名7, age=8, amount=2999)] 150 //GroupBy.Manage(name=姓名2) = [GroupBy.Employee(city=廣東 , name=姓名2, age=10, amount=0)] 151 //GroupBy.Manage(name=姓名1) = [GroupBy.Employee(city=四川, name=姓名1, age=-1, amount=1998)] 152 //GroupBy.Manage(name=姓名0) = [GroupBy.Employee(city=湖南, name=姓名0, age=17, amount=1997)] 153 //GroupBy.Manage(name=姓名6) = [GroupBy.Employee(city=湖北, name=姓名6, age=9, amount=1000)] 154 //GroupBy.Manage(name=姓名5) = [GroupBy.Employee(city=湖北, name=姓名5, age=8, amount=1000)] 155 //GroupBy.Manage(name=姓名4) = [GroupBy.Employee(city=湖南, name=姓名4, age=-3, amount=3000)] 156 //GroupBy.Manage(name=姓名3) = [GroupBy.Employee(city=廣東 , name=姓名3, age=17, amount=1999)] 157 } 158 159 /** 160 * 使用java8 stream groupingBy操作, 基於city 和name 實現多次分組 161 */ 162 public void groupingBys() { 163 Map<String, Map<String, List<Employee>>> map = employees.stream() 164 .collect(Collectors.groupingBy(Employee::getCity, Collectors.groupingBy(Employee::getName))); 165 166 map.forEach((k, v) -> { 167 System.out.println(k + " = " + v); 168 v.forEach((i, j) -> System.out.println(i + " = " + j)); 169 }); 170 //四川 = {姓名6=[GroupBy.Employee(city=四川, name=姓名6, age=-3, amount=997)]} 171 //姓名6 = [GroupBy.Employee(city=四川, name=姓名6, age=-3, amount=997)] 172 173 //湖南 = {姓名5=[GroupBy.Employee(city=湖南, name=姓名5, age=-2, amount=0)]} 174 //姓名5 = [GroupBy.Employee(city=湖南, name=姓名5, age=-2, amount=0)] 175 176 //湖北 = {姓名4=[GroupBy.Employee(city=湖北, name=姓名4, age=10, amount=-2)], 姓名3=[GroupBy.Employee(city=湖北, name=姓名3, age=8, amount=997)], 姓名2=[GroupBy.Employee(city=湖北, name=姓名2, age=8, amount=999)], 姓名9=[GroupBy.Employee(city=湖北, name=姓名9, age=29, amount=-2)], 姓名1=[GroupBy.Employee(city=湖北, name=姓名1, age=30, amount=2000)]} 177 //姓名4 = [GroupBy.Employee(city=湖北, name=姓名4, age=10, amount=-2)] 178 //姓名3 = [GroupBy.Employee(city=湖北, name=姓名3, age=8, amount=997)] 179 //姓名2 = [GroupBy.Employee(city=湖北, name=姓名2, age=8, amount=999)] 180 //姓名9 = [GroupBy.Employee(city=湖北, name=姓名9, age=29, amount=-2)] 181 //姓名1 = [GroupBy.Employee(city=湖北, name=姓名1, age=30, amount=2000)] 182 183 //廣東 = {姓名8=[GroupBy.Employee(city=廣東 , name=姓名8, age=-1, amount=-3)], 姓名7=[GroupBy.Employee(city=廣東 , name=姓名7, age=29, amount=998)], 姓名0=[GroupBy.Employee(city=廣東 , name=姓名0, age=0, amount=2999)]} 184 //姓名8 = [GroupBy.Employee(city=廣東 , name=姓名8, age=-1, amount=-3)] 185 //姓名7 = [GroupBy.Employee(city=廣東 , name=姓名7, age=29, amount=998)] 186 //姓名0 = [GroupBy.Employee(city=廣東 , name=姓名0, age=0, amount=2999)] 187 } 188 189 /** 190 * 使用java8 stream groupingBy操作, 基於Distinct 去重數據 191 */ 192 public void groupingByDistinct() { 193 List<Employee> list = employees.stream().filter(distinctByKey(Employee :: getCity)) 194 .collect(Collectors.toList()); 195 196 list.forEach(item-> System.out.println("city = " + item.getCity())); 197 //city = 湖南 198 //city = 湖北 199 //city = 四川 200 //city = 廣東 201 } 202 203 /** 204 * 自定義重復key 規則 205 */ 206 private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { 207 Set<Object> seen = ConcurrentHashMap.newKeySet(); 208 return t -> seen.add(keyExtractor.apply(t)); 209 } 210 211 public static void main(String[] args) { 212 GroupBy instance = new GroupBy(); 213 instance.init(); 214 instance.groupingByCity(); 215 instance.groupingByCount(); 216 instance.groupingByAverage(); 217 instance.groupingBySum(); 218 instance.groupingByString(); 219 instance.groupingByList(); 220 instance.groupingBySet(); 221 instance.groupingByObject(); 222 instance.groupingBys(); 223 instance.groupingByDistinct(); 224 225 } 226 227 @Data 228 @NoArgsConstructor 229 @AllArgsConstructor 230 class Employee { 231 private String city; 232 private String name; 233 private Integer age; 234 private Integer amount; 235 236 } 237 238 @Data 239 @NoArgsConstructor 240 @AllArgsConstructor 241 class Manage { 242 private String name; 243 244 } 245 246 }
例2:
1 /** 2 * 分組List並顯示其總數 3 */ 4 @Test 5 void test1(){ 6 //3 apple, 2 banana, others 1 7 List items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya"); 8 Map<String, Long> collect = items.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); 9 System.out.println(collect); //{papaya=1, orange=1, banana=2, apple=3} 10 } 11 12 /** 13 * 添加排序 14 */ 15 @Test 16 void test2(){ 17 List<String> items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya"); 18 Map<String, Long> map = items.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); 19 Map<String, Long> finalMap = new LinkedHashMap<>(); 20 map.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed()).forEachOrdered(e->finalMap.put(e.getKey(),e.getValue())); 21 22 System.out.println(finalMap); //{apple=3, banana=2, papaya=1, orange=1} 23 } 24 25 /** 26 * 按姓名+ 數字或數量組合 27 */ 28 @Test 29 void test3(){ 30 //3 apple, 2 banana, others 1 31 List<Item> items = Arrays.asList( 32 new Item("apple", 10, new BigDecimal("9.99")), 33 new Item("banana", 20, new BigDecimal("19.99")), 34 new Item("orange", 10, new BigDecimal("29.99")), 35 new Item("watermelon", 10, new BigDecimal("29.99")), 36 new Item("papaya", 20, new BigDecimal("9.99")), 37 new Item("apple", 10, new BigDecimal("9.99")), 38 new Item("banana", 10, new BigDecimal("19.99")), 39 new Item("apple", 20, new BigDecimal("9.99")) 40 ); 41 Map<String, Long> counting = items.stream().collect(Collectors.groupingBy(Item::getName, Collectors.counting())); 42 System.out.println(counting); //{papaya=1, orange=1, banana=2, apple=3, watermelon=1} 43 44 Map<String, Integer> map = items.stream().collect(Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getNumber))); 45 System.out.println(map); //{papaya=20, orange=10, banana=30, apple=40, watermelon=10} 46 } 47 48 /** 49 * 按價格分組 50 */ 51 @Test 52 void test4(){ 53 //3 apple, 2 banana, others 1 54 List<Item> items = Arrays.asList( 55 new Item("apple", 10, new BigDecimal("9.99")), 56 new Item("banana", 20, new BigDecimal("19.99")), 57 new Item("orange", 10, new BigDecimal("29.99")), 58 new Item("watermelon", 10, new BigDecimal("29.99")), 59 new Item("papaya", 20, new BigDecimal("9.99")), 60 new Item("apple", 10, new BigDecimal("9.99")), 61 new Item("banana", 10, new BigDecimal("19.99")), 62 new Item("apple", 20, new BigDecimal("9.99")) 63 ); 64 Map<BigDecimal, List<Item>> decimalListMap = items.stream().collect(Collectors.groupingBy(Item::getPrice)); 65 System.out.println(decimalListMap); 66 //{19.99=[Item(name=banana, number=20, price=19.99), 67 // Item(name=banana, number=10, price=19.99)], 68 // 29.99=[Item(name=orange, number=10, price=29.99), 69 // Item(name=watermelon, number=10, price=29.99)], 70 // 9.99=[Item(name=apple, number=10, price=9.99), 71 // Item(name=papaya, number=20, price=9.99), 72 // Item(name=apple, number=10, price=9.99), 73 // Item(name=apple, number=20, price=9.99)]} 74 75 Map<BigDecimal, Set<String>> setMap = items.stream().collect(Collectors.groupingBy(Item::getPrice, Collectors.mapping(Item::getName, Collectors.toSet()))); 76 System.out.println(setMap); 77 //{19.99=[banana], 78 // 29.99=[orange, watermelon], 79 // 9.99=[papaya, apple]} 80 }