81 ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊ
π₯ ΠΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠ° ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ Π±Π΅Π· Stream API
ΠΡΡΡ ΠΌΠ΅ΡΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΉ Π³ΡΡΠΏΠΏΠΈΡΡΠ΅Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌ ΠΏΠΎΠ»ΡΠΌ.
public void test() {
List<Item> itemsList = ...//Π§ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ· XML;
Map<List<Object>, List<Item>> groupBy =
itemsList.stream().collect(Collectors.groupingBy(
i -> Arrays.asList(i.id, i.city, i.order_status)));
for (Map.Entry<List<Object>, List<Item>> t : groupBy.entrySet()) {
System.out.println(t.getKey());
for (Item item : t.getValue()) {
System.out.println(" " + item);
}
}
}
ΠΠ°ΠΊ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ°ΠΊΠΎΠ΅ ΠΆΠ΅ Π±Π΅Π· Stream API?
ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΠΌΠ°ΠΏΡ Ρ ΡΠ²Π½ΡΠΌ ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ ΡΠΈΠΏΠ° ΠΊΠ»ΡΡΠ° ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ, Π² ΡΠΈΠΊΠ»Π΅ ΠΏΡΠΎΡ
ΠΎΠ΄ΠΈΡΡ ΠΏΠΎ ΡΠΏΠΈΡΠΊΡ ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π² ΠΌΠ°ΠΏΡ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ
Map::computeIfAbsent -- ΡΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΡΠΎΠ·Π΄Π°ΡΡ Π½ΠΎΠ²ΠΎΠ΅ ΠΈΠ»ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅-ΡΠΏΠΈΡΠΎΠΊ, Π΄Π»Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠ°Π·Ρ ΠΆΠ΅ Π²ΡΠ·Π²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ List:add.
ΠΡΠΈ ΡΡΠΎΠΌ Π»ΡΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ LinkedHashMap, ΡΡΠΎΠ±Ρ ΠΏΠΎΡΡΠ΄ΠΎΠΊ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² Π² Π½Π΅ΠΉ Π±ΡΠ» ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΡΠΉ (HashMap ΠΏΠΎΡΡΠ΄ΠΊΠ° Π½Π΅ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ).
public static Map<List<Object>, List<Item>> groupBy(List<Item> list) {
Map<List<Object>, List<Item>> map = new LinkedHashMap<>();
for (Item item : list) {
List<Object> key = Arrays.asList(item.getId(), item.getCity(), item.getOrderStatus());
map.computeIfAbsent(key, k -> new ArrayList<>()).add(item);
}
return map;
}
Π‘Π»Π΅Π΄ΡΠ΅Ρ ΠΎΡΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Π²ΠΌΠ΅ΡΡΠΎ ΡΠΏΠΈΡΠΊΠ° ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½Π΅Π΅ Π±ΡΠ»ΠΎ Π±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π½Π΅ΠΊΠΈΠΉ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΡΠΉ ΠΊΠ»Π°ΡΡ, Π΄Π»Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π½ΡΠΆΠ½ΠΎ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ hashCode ΠΈ equals.
ΠΡΠΎ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ record, ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΡ
Ρ Java 16, ΠΈΠ»ΠΈ Lombok-Π°Π½Π½ΠΎΡΠ°ΡΠΈΠΉ @Data / @AllArgsConstructor.
enum OrderStatus {NEW, PROCESSING, COMPLETED, CANCELED};
// ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ, Π³Π΅ΡΡΠ΅ΡΡ Π±Π΅Π· ΠΏΡΠ΅ΡΠΈΠΊΡΠ° `get`, hashCode / equals, toString
record MyKey(long id, String city, OrderStatus status) {
public MyKey(Item item) {
this(item.getId(), item.getCity(), item.getOrderStatus());
}
}
public static Map<MyKey, List<Item>> groupBy(List<Item> list) {
Map<MyKey, List<Item>> map = new LinkedHashMap<>();
list.forEach(item -> map
.computeIfAbsent(new MyKey(item), k -> new ArrayList<>())
.add(item)
);
// ΠΎΡΠ»Π°Π΄ΠΎΡΠ½ΡΠΉ Π²ΡΠ²ΠΎΠ΄
map.forEach((key, val) -> {
System.out.println(key);
val.forEach(item -> System.out.println("\t" + item));
});
return map;
}
ΠΡΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ°ΠΊΠΎΠΉ Π³ΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ Π»ΡΠ±ΠΎΠ³ΠΎ ΠΊΠ»ΡΡΠ°, Π΅ΡΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π½Π΅ΠΊΡΡ ΡΡΠ½ΠΊΡΠΈΡ-ΠΊΠΎΠ½Π²Π΅ΡΡΠΎΡ Function<Item, Key>, Π² ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΡΠ°ΠΊΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ Π±ΡΠ» ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ ΠΊΠΎΡΡΠ΅ΠΆΠ° MyKey(Item item). ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ ΠΊΠ»ΡΡΠ°-ΡΠΏΠΈΡΠΊΠ° ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π±Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠ°Π±ΡΠΈΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄:
// MyClass
public static List<Object> keyIdCityStatus(Item item) {
return Arrays.asList(item.getId(), item.getCity(), item.getOrderStatus());
}
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ:
public static<K> Map<K, List<Item>> groupBy(Function<Item, K> keyBuilder, List<Item> list) {
Map<K, List<Item>> map = new LinkedHashMap<>();
list.forEach(item -> map
.computeIfAbsent(keyBuilder.apply(item), k -> new ArrayList<>())
.add(item)
);
return map;
}
Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π»Ρ Π»ΡΠ±ΠΎΠ³ΠΎ ΠΊΠ»ΡΡΠ°:
// ΡΡΡΠ»ΠΊΠ° Π½Π° ΡΠ°Π±ΡΠΈΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ MyClass::keyIdCityStatus
Map<List<Object>, List<Item>> keyListMap = groupBy(MyClass::keyIdCityStatus, list);
// ΡΡΡΠ»ΠΊΠ° Π½Π° ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ MyKey::new
Map<MyKey, List<Item>> keyRecordMap = groupBy(MyKey::new, list);
2 ΠΌΠΈΠ½ΡΡΡ
7Β ΠΌΠ°ΡΡΠ°Β 2023