BanditBool2 / ReadingRecord

2 stars 0 forks source link

[Ch6] 6.3 그룹화 #40

Closed kkambbak closed 1 year ago

kkambbak commented 1 year ago

211 페이지에서 dish들을 enum CaloricLevel{DIET, NORMAL, FAT}을 기준으로 groupBy로 그룹화합니다. enum말고 클래스로도 적용이 가능할까요? 아니면 클래스나 enum이 아니더라도 groupBy를 활용하는 방법이 있을까요?

chaewon-io commented 1 year ago

1. 클래스로도 가능합니다. CaloricLevel을 나타내는 클래스를 만들고 해당 클래스의 인스턴스를 사용하여 그룹화 할 수 있습니다.

class Dish {
    private String name;
    private int calories;
    private CaloricLevel caloricLevel;

    public Dish(String name, int calories) {
        this.name = name;
        this.calories = calories;
        if (calories <= 400) {
            this.caloricLevel = CaloricLevel.DIET;
        } else if (calories <= 700) {
            this.caloricLevel = CaloricLevel.NORMAL;
        } else {
            this.caloricLevel = CaloricLevel.FAT;
        }
    }

    public CaloricLevel getCaloricLevel() {
        return caloricLevel;
    }

    // getters and setters
}

class CaloricLevel {
    private String name;

    public CaloricLevel(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

List<Dish> menu = ... 
Map<CaloricLevel, List<Dish>> dishesByCaloricLevel =
    menu.stream().collect(Collectors.groupingBy(dish -> new CaloricLevel(dish.getCaloricLevel().getName())));

위 코드에서 CaloricLevel 클래스는 name 속성을 가지며, 해당 클래스의 인스턴스를 사용하여 Dish 객체를 그룹화합니다. 그러나 enum으로 대체하면 더 간단한 코드로 작성할 수 있습니다.

2. groupBy()메서드를 활용하는 방법도 있습니다.

groupBy() 메서드는 특정 키를 기준으로 그룹화된 맵(Map)을 반환합니다. 이를 이용해서 클래스나 enum이 아니더라도 groupBy() 메서드를 활용하는 방법이 있습니다.

List<Dish> dishes = new ArrayList<>();
// dishes 리스트에 Dish 객체들을 추가

Map<CaloricLevel, List<Dish>> dishesByCaloricLevel = dishes.stream()
    .collect(Collectors.groupingBy(dish -> {
        if (dish.getCalories() <= 400) {
            return CaloricLevel.DIET;
        } else if (dish.getCalories() <= 700) {
            return CaloricLevel.NORMAL;
        } else {
            return CaloricLevel.FAT;
        }
    }));

위 코드에서는 Collectors.groupingBy() 메서드에 calories 필드를 기준으로 그룹화하는 함수를 제공하여 dishes 스트림을 그룹화하였습니다. 그 결과로 dishesByCaloricLevel 맵은 CaloricLevel enum 값에 따라 Dish 객체들이 그룹화된 것을 확인할 수 있습니다.

또 다른 예로, groupBy() 메소드는 Function 인터페이스를 인수로 받으므로, 해당 인터페이스를 구현한 람다식을 사용하여 그룹화할 수 있습니다.

List<String> words = Arrays.asList("apple", "banana", "orange", "pear", "watermelon");
Map<Character, List<String>> wordsByFirstChar = words.stream()
        .collect(Collectors.groupingBy(word -> word.charAt(0)));
``