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

박범식 과제완료~! #3

Open
wants to merge 3 commits into
base: 24ParkBumShik
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 @@ -4,11 +4,14 @@
import org.speculatingwook.library.book.BookTransformer;
import org.speculatingwook.library.book.BookValidator;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;

public class LibraryService {
private List<Book> books = new ArrayList<>();
Expand All @@ -24,7 +27,7 @@ public void addBook(Book book) {
* @return 조건에 맞는 책들의 리스트
*/
public List<Book> findBooks(Predicate<Book> predicate) {
return null;
return books.stream().filter(predicate).toList();
}


Expand All @@ -33,7 +36,7 @@ public List<Book> findBooks(Predicate<Book> predicate) {
* @return 저자별 책 리스트 맵
*/
public Map<String, List<Book>> groupBooksByAuthor() {
return null;
return books.stream().collect(Collectors.groupingBy(Book::getAuthor));
}

/**
Expand All @@ -42,7 +45,12 @@ public Map<String, List<Book>> groupBooksByAuthor() {
* @return 카테고리별 책의 개수
*/
public Map<String, Long> countBooksByCategory() {
return null;
return books.stream()
.flatMap(book -> book.getCategories().stream())
.collect(Collectors.groupingBy(
category -> category,
Collectors.counting()
));
}

/**
Expand All @@ -52,7 +60,17 @@ public Map<String, Long> countBooksByCategory() {
* @return 인기 카테고리 리스트
*/
public List<String> getMostPopularCategories(int n) {
return null;
return books.stream()
.flatMap(book -> book.getCategories().stream())
.collect(Collectors.groupingBy(
category -> category,
Collectors.counting()
))
.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Collections.reverseOrder()))
.limit(n)
.map(Map.Entry::getKey)
.toList();
}

/**
Expand All @@ -61,7 +79,9 @@ public List<String> getMostPopularCategories(int n) {
* @return 평균 책 나이
*/
public double getAverageBookAge() {
return 0;
return books.stream()
.mapToLong(book -> ChronoUnit.YEARS.between(book.getPublishDate(), LocalDate.now()))
.average().getAsDouble();
}

/**
Expand All @@ -71,7 +91,10 @@ public double getAverageBookAge() {
* @return 최근 책들의 리스트
*/
public List<Book> getRecentBooks(int n) {
return null;
return books.stream()
.sorted(Comparator.comparing(Book::getPublishDate).reversed())
.limit(n)
.toList();
}

/**
Expand All @@ -80,23 +103,34 @@ public List<Book> getRecentBooks(int n) {
* @return 대출 성공 여부
*/
public boolean lendBook(String isbn) {
return false;
return books.stream()
.filter(book -> book.getIsbn().equals(isbn) && book.isAvailable())
.findFirst()
.map(book -> {
book.setAvailable(false);
return true;
})
.orElse(false);
}

/**
* 7 - 2. 책을 반납합니다.
* @param isbn 반납할 책의 ISBN 번호
*/
public void returnBook(String isbn) {

books.stream()
.filter(book -> book.getIsbn().equals(isbn))
.findFirst()
.ifPresent(book -> book.setAvailable(true));
}


/**
* 8. 책을 대출 가능 여부에 따라 구분합니다.
* @return 대출 가능 여부에 따른 책들의 맵
*/
public Map<Boolean, List<Book>> partitionBooksByAvailability() {
return null;
return books.stream().collect(Collectors.partitioningBy(Book::isAvailable));
}

/**
Expand All @@ -105,7 +139,14 @@ public Map<Boolean, List<Book>> partitionBooksByAvailability() {
* @return 가장 많은 책을 출판한 저자
*/
public String getMostProlificAuthor() {
return null;
return books.stream()
.collect(Collectors.groupingBy(
Book::getAuthor,
Collectors.counting()
))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.get().getKey();
}


Expand All @@ -115,7 +156,10 @@ public String getMostProlificAuthor() {
* @return 책 제목의 총 길이
*/
public int getTotalTitleLength() {
return 0;
return books.stream()
.map(Book::getTitle)
.collect(Collectors.joining())
.length();
}

/**
Expand All @@ -133,7 +177,7 @@ public void processBooks(BookProcessor processor) {
* @return 검증된 책 리스트
*/
public List<Book> getValidBooks(BookValidator validator) {
return null;
return books.stream().filter(validator::validate).toList();
}

/**
Expand All @@ -143,15 +187,15 @@ public List<Book> getValidBooks(BookValidator validator) {
* @return 변환된 결과 리스트
*/
public <T> List<T> transformBooks(BookTransformer<T> transformer) {
return null;
return books.stream().map(transformer::transform).toList();
}

/**
* 14. Supplier를 사용하여 새 책을 생성합니다.
* @param bookSupplier 새 책을 생성할 Supplier
*/
public void addNewBook(Supplier<Book> bookSupplier) {

books.add(bookSupplier.get());
}

/**
Expand All @@ -160,7 +204,7 @@ public void addNewBook(Supplier<Book> bookSupplier) {
* @return 찾은 책 (Optional로 감싸진 값)
*/
public Optional<Book> findBookByIsbn(String isbn) {
return null;
return books.stream().filter(book -> book.getIsbn().equals(isbn)).findFirst();
}

/**
Expand All @@ -172,7 +216,7 @@ public Optional<Book> findBookByIsbn(String isbn) {
* @return 비교 결과
*/
public <T> T compareBooks(Book book1, Book book2, BiFunction<Book, Book, T> comparator) {
return null;
return comparator.apply(book1, book2);
}

/**
Expand All @@ -181,9 +225,7 @@ public <T> T compareBooks(Book book1, Book book2, BiFunction<Book, Book, T> comp
* @param updater 책을 업데이트할 UnaryOperator
*/
public void updateBookState(String isbn, UnaryOperator<Book> updater) {
findBookByIsbn(isbn).ifPresent(book -> {
// TODO: 이 부분을 채워주세요
});
findBookByIsbn(isbn).ifPresent(updater::apply);
}

}
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,45 +17,78 @@ public void addOrder(Order order) {

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

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


// 가장 많이 주문된 제품을 찾습니다.
// 일단 제대로 된 값이 나올 수 있도록 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)
.orElseThrow(() -> new NoSuchElementException("No product found"));
}


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


// 주문 상태를 업데이트합니다.
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).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(item->item.getProducts().stream()
.collect(Collectors.summingDouble(Product::getPrice)))))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.get();
}
// 질문: String은 이 함수에서 사용하기 좋은 타입인가? 만약 아니라면 어떻게 바꾸는 게 더 좋을까?


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

// 주문들을 특정 기준으로 정렬합니다.
public List<Order> sortOrders(Comparator<Order> orderComparator) {
return null;
return orders.stream().sorted(orderComparator).toList();
}
}
Loading