Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[김영록] 2차시 미션 제출합니다. #12

Open
wants to merge 3 commits into
base: 24kimyeoungrok
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;

public class OrderProcessingService {
private List<Order> orders = new ArrayList<>();
Expand All @@ -16,44 +17,82 @@ public void addOrder(Order order) {

// 주문 총액이 특정 금액 이상인 주문들을 찾습니다.
public List<Order> findHighValueOrders(double minTotal) {
return null;
return orders.stream()
.filter(order -> order.getProducts().stream()
.mapToDouble(Product::getPrice)
.sum() > minTotal)
.collect(Collectors.toList());
}

// 각 고객별 총 주문 금액을 계산합니다.
public Map<String, Double> calculateTotalOrderValuePerCustomer() {
return null;
return orders.stream()
.collect(Collectors.groupingBy(
Order::getCustomerId,
Collectors.summingDouble(order -> order.getProducts().stream()
.mapToDouble(Product::getPrice)
.sum())
));
}

// 가장 많이 주문된 제품을 찾습니다.
// 일단 제대로 된 값이 나올 수 있도록 streamAPI를 사용해서 작성해보자. 이 코드에서 발생할 수 있는 문제가 있을까?
public Product findMostOrderedProduct() {
return null;
return orders.stream()
.flatMap(order -> order.getProducts().stream())
.collect(Collectors.groupingBy(product -> product, Collectors.counting()))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(null);
}

// 특정 기간 동안의 일일 매출을 계산합니다.
public Map<LocalDate, Double> calculateDailySales(LocalDate startDate, LocalDate endDate) {
return null;
return orders.stream()
.filter(order -> !order.getOrderDate().isBefore(startDate) && !order.getOrderDate().isAfter(endDate))
.collect(Collectors.groupingBy(
Order::getOrderDate,
Collectors.summingDouble(order -> order.getProducts().stream()
.mapToDouble(Product::getPrice)
.sum())
));
}

// 주문 상태를 업데이트합니다.
public void updateOrderStatus(String orderId, UnaryOperator<String> statusUpdater) {

orders.stream()
.filter(order -> order.getId().equals(orderId))
.findFirst()
.ifPresent(order -> order.setStatus(statusUpdater.apply(order.getStatus())));
}

// 조건에 맞는 주문들의 특정 정보를 추출합니다.
public <T> List<T> extractOrderInfo(Predicate<Order> filter, Function<Order, T> infoExtractor) {
return null;
return orders.stream()
.filter(filter)
.map(infoExtractor)
.collect(Collectors.toList());
}

// 각 카테고리별 판매 수량을 계산합니다.
public Map<String, Long> countSalesByCategory() {
return null;
return orders.stream()
.flatMap(order -> order.getProducts().stream())
.collect(Collectors.groupingBy(Product::getCategory, Collectors.counting()));
}

// 주어진 기간 동안 가장 많은 매출을 올린 고객을 찾습니다.
// 질문: String은 이 함수에서 사용하기 좋은 타입인가? 만약 아니라면 어떻게 바꾸는 게 더 좋을까?
public String findTopCustomer(LocalDate startDate, LocalDate endDate) {
return null;
return orders.stream()
.filter(order -> !order.getOrderDate().isBefore(startDate) && !order.getOrderDate().isAfter(endDate))
.collect(Collectors.groupingBy(Order::getCustomerId, Collectors.summingDouble(order ->
order.getProducts().stream().mapToDouble(Product::getPrice).sum())))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse("");
}

// 모든 주문에 대해 주어진 작업을 수행합니다.
Expand All @@ -63,6 +102,8 @@ public void processOrders(Consumer<Order> orderProcessor) {

// 주문들을 특정 기준으로 정렬합니다.
public List<Order> sortOrders(Comparator<Order> orderComparator) {
return null;
return orders.stream()
.sorted(orderComparator)
.collect(Collectors.toList());
}
}
112 changes: 92 additions & 20 deletions lambda/src/main/java/org/speculatingwook/user/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class UserService {
private List<User> users = new ArrayList<>();
Expand All @@ -17,47 +18,71 @@ public void addUser(User user) {
* @return 사용자 이름 목록
*/
public List<String> getAllUserNames() {
return null;
List<String> names = new ArrayList<>();
for(User user : users){
names.add(user.getName());
}
return names;
}

/**
* 2. 나이순으로 사용자 목록을 정렬한다.
* @return 나이순으로 정렬된 사용자 목록
*/
public List<User> getUsersSortedByAge() {
return null;
users.sort(Comparator.comparingInt(User::getAge)); // 이렇게도 쓸 수 있구나 ㄷㄷ
return users;
}

/**
* 3. 나이가 30 이상인 사용자 목록을 반환한다.
* @return 나이가 30 이상인 사용자 목록
*/
public List<User> getUsersOver30() {
return null;
List<User> userOver30 = new ArrayList<>();
for(User user : users){
if(user.getAge() >= 30){
userOver30.add(user);
}
}
return userOver30;
}

/**
* 4. 부서별로 사용자 목록을 그룹화한다.
* @return 부서별 사용자 목록
*/
public Map<String, List<User>> groupUsersByDepartment() {
return null;
Map<String, List<User>> groupUserMap = new HashMap<>();
for(User user : users){
groupUserMap.computeIfAbsent(user.getDepartment(), k -> new ArrayList<>());
groupUserMap.get(user.getDepartment()).add(user);
}
return groupUserMap;
}

/**
* 5. 모든 사용자의 나이 합을 계산한다.
* @return 사용자 나이 합
*/
public int getTotalAge() {
return 0;
int totalAge = 0;
for(User user : users){
totalAge += user.getAge();
}
return totalAge;
}

/**
* 6. 모든 사용자의 평균 급여를 계산한다.
* @return 평균 급여
*/
public double getAverageSalary() {
return 0;
double totalSalary = 0;
for(User user : users){
totalSalary += user.getSalary();
}
return totalSalary / users.size();
}

/**
Expand All @@ -67,16 +92,23 @@ public double getAverageSalary() {
* @return 나이 범위 내의 사용자 목록
*/
public List<User> getUsersInAgeRange(int minAge, int maxAge) {
return null;
List<User> usersInAgeRange = new ArrayList<>();
for(User user : users){
if(user.getAge() >= minAge && user.getAge() <= maxAge){
usersInAgeRange.add(user);
}
}
return usersInAgeRange;
}

/**
* 8. 특정 이름을 가진 사용자를 검색한다.
* @param name 사용자 이름
* @return 이름이 일치하는 사용자
*/
// stream : 객체들 하나씩 가져오는 거
public Optional<User> findUserByName(String name) {
return null;
return users.stream().filter(user -> user.getName().equals(name)).findAny();
}

/**
Expand All @@ -85,7 +117,12 @@ public Optional<User> findUserByName(String name) {
* @return 모든 사용자가 해당 나이 이상이면 true, 아니면 false
*/
public boolean areAllUsersAboveAge(int age) {
return false;
for(User user : users){
if(user.getAge() < age){
return false;
}
}
return true;
}

/**
Expand All @@ -94,23 +131,30 @@ public boolean areAllUsersAboveAge(int age) {
* @return 조건에 맞는 사용자
*/
public Optional<User> findUser(Predicate<User> predicate) {
return null;
return users.stream().filter(predicate).findAny();
}

/**
* 11. 부서별로 가장 나이가 많은 사용자를 찾는다.
* @return 부서별 가장 나이 많은 사용자
*/
public Map<String, User> getOldestUserByDepartment() {
return null;
Map<String, List<User>> groupUsers = groupUsersByDepartment();
Map<String, User> oldestUser = new HashMap<>();
for (String key : groupUsers.keySet()) {
groupUsers.get(key).sort(Comparator.comparingInt(User::getAge));
oldestUser.put(key, groupUsers.get(key).getLast());
}
return oldestUser;
}

/**
* 12. 이름의 길이가 가장 긴 사용자를 찾는다.
* @return 이름이 가장 긴 사용자
*/
public Optional<User> getUserWithLongestName() {
return null;
return users.stream()
.max(Comparator.comparingInt(user -> user.getName().length()));
}

/**
Expand All @@ -119,7 +163,10 @@ public Optional<User> getUserWithLongestName() {
* @return 대문자로 변환된 사용자 이름 목록
*/
public List<String> getUpperCaseNamesOfUsersAboveAge(int age) {
return null;
return users.stream()
.filter(user -> user.getAge() >= age)
.map(user -> user.getName().toUpperCase())
.toList();
}

/**
Expand All @@ -129,31 +176,47 @@ public List<String> getUpperCaseNamesOfUsersAboveAge(int age) {
* @return 변환된 사용자 목록
*/
public <R> List<R> mapUsers(Function<User, R> mapper) {
return null;
return users.stream()
.map(mapper)
.collect(Collectors.toList());
}

/**
* 15. 모든 사용자 이름을 연결하여 하나의 문자열로 만든다.
* @return 연결된 사용자 이름 문자열
*/
public String getAllUserNamesToString() {
return null;
return users.stream()
.map(User::getName)
.collect(Collectors.joining(", "));
}

/**
* 16-1. 부서별 평균 나이를 계산한다.
* @return 부서별 평균 나이
*/
public Map<String, Double> getAverageAgeByDepartment() {
return null;
return users.stream()
.collect(Collectors.groupingBy(
User::getDepartment,
Collectors.averagingDouble(User::getAge)
));
}

/**
* 16-2. 부서별 평균 나이를 기준으로 부서를 내림차순으로 정렬한다.
* @return 정렬된 부서 목록과 평균 나이
*/
public List<Map.Entry<String, Double>> getDepartmentsSortedByAverageAge() {
return null;
return users.stream()
.collect(Collectors.groupingBy(
User::getDepartment,
Collectors.averagingDouble(User::getAge)
))
.entrySet()
.stream()
.sorted(Map.Entry.<String, Double>comparingByValue().reversed())
.collect(Collectors.toList());
}

/**
Expand All @@ -162,7 +225,9 @@ public List<Map.Entry<String, Double>> getDepartmentsSortedByAverageAge() {
* @return 필터링된 사용자 목록
*/
public List<User> filterUsers_1(Predicate<User> predicate) {
return null;
return users.stream()
.filter(predicate)
.collect(Collectors.toList());
}

/**
Expand All @@ -171,29 +236,36 @@ public List<User> filterUsers_1(Predicate<User> predicate) {
* @return 필터링된 사용자 목록
*/
public List<User> filterUsers_2(Predicate<User> predicate) {
return null;
return users.stream()
.filter(predicate)
.collect(Collectors.toList());
}

/**
* 19. 주어진 작업을 각 사용자에게 수행한다.
* @param consumer 작업
*/
public void processUsers(Consumer<User> consumer) {
users.forEach(consumer);
}

/**
* 20. 사용자 목록을 주어진 비교 기준에 따라 정렬한다.
* @param comparator 비교 기준
*/
public void sortUsers(Comparator<User> comparator) {
users.sort(comparator);
}

/**
* 21. 모든 사용자의 평균 나이를 계산한다.
* @return 평균 나이
*/
public double getAverageAge() {
return 0;
return users.stream()
.mapToInt(User::getAge) // 각 사용자의 나이를 IntStream으로 변환
.average()
.orElse(0.0);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ void testFindTopCustomer() {
LocalDate.of(2023, 1, 1),
LocalDate.of(2023, 1, 7)
);
assertTrue(topCustomer.isEmpty());
assertFalse(topCustomer.isEmpty());
assertEquals("C1", topCustomer);
}

Expand Down
Loading