함수형 인터페이스를 이어주는 것
andThen() : 왼쪽 -> 오른쪽,
compose() : 오른쪽 -> 왼쪽
인터페이스AB = 인터페이스A.andThen(인터페이스B); 최종결과 = 인터페이스AB.method();
인터페이스AB = 인터페이스A.compose(인터페이스B); 최종결과 = 인터페이스AB.method();
andThen()
package com.test;
import java.util.function.Consumer;
class Member {
private String name;
private String id;
private Address address;
public Member(String name, String id, Address address) {
this.name = name;
this.id = id;
this.address = address;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public Address getAddress() {
return address;
}
}
class Address {
private String country;
private String city;
public Address(String country, String city) {
this.country = country;
this.city = city;
}
public String getCountry() {
return country;
}
public String getCity() {
return city;
}
}
public class MyTest {
public static void main(String[] args) {
Consumer memberNameConsumer = m -> System.out.println("memberNameConsumer: " + m.getName());
Consumer memberIdConsumer = m -> System.out.println("memberIdConsumer: " + m.getId());
Consumer<Member> memberNameIdConsumer = memberNameConsumer.andThen(memberIdConsumer);
memberNameIdConsumer.accept(new Member("홍길동", "HGD", null));
Consumer<Member> memberIdNameConsumer = memberIdConsumer.andThen(memberNameConsumer);
memberIdNameConsumer.accept(new Member("홍길동", "HGD", null));
}
}
![](https://velog.velcdn.com/images/letthem/post/ff59f75a-51e7-4c52-96ca-4a11dbf0127a/image.png)
#### compose()
```java
package com.test;
import java.util.function.Consumer;
import java.util.function.Function;
class Member {
private String name;
private String id;
private Address address;
public Member(String name, String id, Address address) {
this.name = name;
this.id = id;
this.address = address;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public Address getAddress() {
return address;
}
}
class Address {
private String country;
private String city;
public Address(String country, String city) {
this.country = country;
this.city = city;
}
public String getCountry() {
return country;
}
public String getCity() {
return city;
}
}
public class MyTest {
public static void main(String[] args) {
Function<Member, Address> getAddressFromMember = m -> m.getAddress();
Function<Address,String> getCityFromAddress = a -> a.getCity();
Function<Member, String> getCityFromMember;
String city;
getCityFromMember = getAddressFromMember.andThen(getCityFromAddress);
city = getCityFromMember.apply(new Member("홍길동", "HGD", new Address("한국", "서울")));
System.out.println(city);
getCityFromMember = getCityFromAddress.compose(getAddressFromMember);
city = getCityFromMember.apply(new Member("홍길동", "HGD", new Address("한국", "서울")));
System.out.println(city);
}
}
package com.test;
import java.util.function.IntPredicate;
public class MyTest {
public static void main(String[] args) {
IntPredicate predicate2x = n -> n % 2 == 0;
IntPredicate predicate3x = n -> n % 3 == 0;
IntPredicate predicate;
boolean result;
predicate = predicate2x.and(predicate3x);
result = predicate.test(9);
System.out.println("숫자 9는 2와 3의 배수입니까? " + result);
predicate = predicate2x.or(predicate3x);
result = predicate.test(9);
System.out.println("숫자 9는 2 또는 3의 배수입니까? " + result);
predicate = predicate2x.negate();
result = predicate.test(9);
System.out.println("숫자 9는 2의 배수가 아닙니까? " + result);
}
}
package com.test;
import java.util.function.IntPredicate;
import java.util.function.Predicate;
public class MyTest {
public static void main(String[] args) {
Predicate<String> predicate;
boolean result;
predicate = Predicate.isEqual(null);
result = predicate.test(null);
System.out.println("null == null : " + result);
predicate = Predicate.isEqual("Java");
result = predicate.test(null);
System.out.println("Java == null : " + result);
predicate = Predicate.isEqual(null);
result = predicate.test("Java");
System.out.println("null == Java : " + result);
predicate = Predicate.isEqual("Java");
result = predicate.test("Java");
System.out.println("Java == Java : " + result);
}
}
string이 아닌 객체가 들어올 때 쓸 수 있을듯,, 근데 별로 쓸 일 없을 것 같다.
BinaryOperator<T> 함수형 인터페이스에서 제공하는 정적 메서드로,
매개변수로 Comparator<T> 함수형 인터페이스를 제공
package com.test;
import java.util.function.BinaryOperator;
import java.util.function.IntPredicate;
import java.util.function.Predicate;
class Fruit {
private String name;
private int price;
public Fruit(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return this.name;
}
public int getPrice() {
return this.price;
}
}
public class MyTest {
public static void main(String[] args) {
BinaryOperator<Fruit> bio;
Fruit fruit;
bio = BinaryOperator.minBy((f1, f2) -> Integer.compare(f1.getPrice(), f2.getPrice()));
fruit = bio.apply(new Fruit("딸기", 12000), new Fruit("사과", 9000));
System.out.println(fruit.getName());
bio = BinaryOperator.maxBy((f1, f2) -> Integer.compare(f1.getPrice(), f2.getPrice()));
fruit = bio.apply(new Fruit("딸기", 12000), new Fruit("사과", 9000));
System.out.println(fruit.getName());
}
}
자바8에서 추가된 컬렉션(배열 포함)의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해 주는 반복자
함수형 인터페이스를 이용해서 선언하는 형태로 코드를 만들 수 있다!!!
=> 람다식이나 메서드 참조형 사용할 수 있다 !
람다식과 짝꿍 🩷
import org.w3c.dom.ls.LSOutput;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
public class Example {
public static void main(String[] args) {
List<String> lists = Arrays.asList("aaa", "bbb", "ccc");
// Iterator
Iterator<String> it = lists.iterator();
while (it.hasNext()) {
String item = it.next();
System.out.println(item);
}
// Stream
Stream<String> st = lists.stream();
st.forEach(item -> System.out.println(item));
st = lists.stream();
st.forEach(System.out::println);
}
}
람다식 또는 메서드 참조로 요소 처리 코드를 제공한다.
이것만 잘하면 됨 !!!!! ⭐️⭐️⭐️⭐️⭐️ ⬇️
lists.stream().map(String::toUpperCase).forEach(System.out::println);
리스트를 stream (돌면서) 대문자로 map(바꾸고) forEach(돌면서 각각) 출력하기
import lombok.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
@Getter
@AllArgsConstructor
class Student {
String name;
int Score;
}
public class Example {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("홍길동", 90), new Student("고길동", 80),
new Student("임길동", 90), new Student("이길동", 80),
new Student("삼길동", 90), new Student("사길동", 80));
Stream<Student> stream = students.stream();
stream.forEach(s -> System.out.printf("%s : %d\n", s.getName(), s.getScore()));
// forEach() : List 인터페이스의 default 메서드 -> Stream 없이도 리스트 요소를 반복 처리 가능
students.forEach(s -> System.out.printf("%s : %d\n", s.getName(), s.getScore()));
}
}
import lombok.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
@Getter
@AllArgsConstructor
class Student {
String name;
int Score;
}
public class Example {
public static void print(Student s) {
System.out.printf("[%s] %s : %d\n", Thread.currentThread().getName(), s.getName(), s.getScore());
}
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("홍길동", 90), new Student("고길동", 80),
new Student("임길동", 90), new Student("이길동", 80),
new Student("삼길동", 90), new Student("사길동", 80));
// 순차 처리
Stream<Student> stream = students.stream();
stream.forEach(Example::print);
System.out.println();
// 병렬 처리
Stream<Student> parallelStream = students.parallelStream();
parallelStream.forEach(Example::print);
}
}
Thread, Stream
대용량 데이터를 처리할 때 병렬 처리로 하면 효율적이다.
worker 들이 같이 처리해준다!!
Stream을 사용하면 데이터를 원하는 대로 가공하고 결과물을 뽑아낼 수 있다.
import lombok.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
@Getter
@AllArgsConstructor
class Student {
String name;
int Score;
}
public class Example {
public static void print(Student s) {
System.out.printf("[%s] %s : %d\n", Thread.currentThread().getName(), s.getName(), s.getScore());
}
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("홍길동", 90), new Student("고길동", 80),
new Student("임길동", 90), new Student("이길동", 80),
new Student("삼길동", 90), new Student("사길동", 80));
double average = students.stream()
.mapToInt(Student::getScore) // 학생의 점수를 맵핑
.average()
.getAsDouble();
System.out.println(average);
}
}
import lombok.*;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class Example {
public static void main(String[] args) {
String[] strArr = { "홍길동", "고길동", "신길동" };
Stream<String> strStm = Arrays.stream(strArr);
strStm.forEach(s -> System.out.println(s));
strStm = Arrays.stream(strArr);
strStm.forEach(System.out::println);
int[] intArr = { 10, 20, 30 };
IntStream intStm = Arrays.stream(intArr);
intStm.forEach(s -> System.out.println(s));
}
}
1부터 100까지 더하기 & 1부터 99까지 더하기 ⬇️
import java.util.stream.IntStream;
public class Example {
public static int sum = 0;
public static void main(String[] args) {
IntStream stream = IntStream.rangeClosed(1, 100); // 1 ~ 100까지 추출
stream.forEach(n -> sum += n);
System.out.println(sum); // 5050
sum = 0;
IntStream stream2 = IntStream.range(1, 100); // 1 ~ 99까지 추출
stream2.forEach(n -> sum += n);
System.out.println(sum); // 4950
}
}
평균 나이 계산 ⬇️
import lombok.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Locale.filter;
@AllArgsConstructor
@Getter
class Member {
public static int MALE = 0;
public static int FEMALE = 1;
private String name;
private int gender;
private int age;
}
public class Example {
public static void main(String[] args) throws IOException {
List<Member> members = Arrays.asList(
new Member("홍길동", Member.MALE, 30),
new Member("고길동", Member.MALE, 40),
new Member("이하니", Member.FEMALE, 20),
new Member("삼하니", Member.FEMALE, 30));
double maleAvgAge = members.stream()
.filter(m -> m.getGender() == Member.MALE)
// .mapToInt(m -> m.getAge())
.mapToInt(Member::getAge)
.average()
.getAsDouble();
System.out.println("남자 평균 나이 : " + maleAvgAge);
}
}
import lombok.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Locale.filter;
public class Example {
public static void main(String[] args) throws IOException {
List<String> stations = Arrays.asList("부평시장", "홍대입구", "강남", "신도림", "역삼", "삼성", "신림", "부평구청", "신도림");
stations.stream()
.distinct()
.forEach(System.out::println);
System.out.println();
stations.stream()
.filter(s -> s.startsWith("신"))
.forEach(System.out::println);
System.out.println();
stations.stream()
.filter(s -> s.startsWith("신"))
.distinct()
.forEach(System.out::println);
}
}
n : n
으로 새롭게 만들어진다.
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Example {
public static void main(String[] args) throws IOException {
List<String> list1 = Arrays.asList("java8 lambda", "stream mapping api");
list1.stream()
.flatMap(d -> Arrays.stream(d.split(" ")))
.forEach(System.out::println);
}
}
배열을 stream으로 바꾼다.
flatMap() : 데이터의 개수가 바뀔 수 있다. 기준에 맞춰(여기선 공백으로 자르기) 스트림으로 만들어주는 것
flatMapXXX()
flatMapToInt() ⬇️
import lombok.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Example {
public static void main(String[] args) throws IOException {
List<String> list2 = Arrays.asList("10, 20, 30, 40, 50, 60");
list2.stream()
.flatMapToInt(d -> {
String[] strArray = d.split(",");
int[] intArray = new int[strArray.length];
for (int i = 0; i < strArray.length; i++) {
intArray[i] = Integer.parseInt(strArray[i].trim());
}
return Arrays.stream(intArray);
})
.forEach(System.out::println);
}
}
import lombok.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@Getter
@AllArgsConstructor
class Student {
String name;
int score;
}
public class Example {
public static void main(String[] args) throws IOException {
List<Student> students = Arrays.asList(
new Student("홍길동", 90), new Student("고길동", 80),
new Student("일길동", 90), new Student("이길동", 80),
new Student("삼길동", 90), new Student("사길동", 80));
students.stream()
.mapToInt(Student::getScore)
.forEach(System.out::println);
}
}
컬렉션 프레임워크 + 함수형 프로그래밍을 사용해서 만들어보자 !
도서 등록, 전체 조회, 검색, 삭제, 인기 도서 검색 등의 기능을 제공
도서정보 : ISBN, 제목, 저자, 출판연도
(Entity)
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
@AllArgsConstructor
@Getter
@ToString
public class Book {
private String isbn;
private String title;
private String author;
private int year;
}
(Service)
import java.util.*;
public class LibraryManagement {
// 변수들 ⬇️
// 도서 정보
private List<Book> books = new ArrayList<>();
// ISBN => 도서 등록 시 동일 도서가 존재하는지 확인
private Set<String> isbnSet = new HashSet<>();
// 조회수 => ISBN, 조회수 정보를 관리
private Map<String, Integer> bookViews = new HashMap<>();
// 기능 함수들 ⬇️
// 도서 등록
public void addBook(Book book) {
if (isbnSet.contains(book.getIsbn())) {
System.out.printf("ISBN %s과 동일한 도서가 이미 등록되어 있습니다.\n", book.getIsbn());
return;
}
books.add(book);
isbnSet.add(book.getIsbn());
bookViews.put(book.getIsbn(), 0);
System.out.println("정상적으로 등록되었습니다." + book);
}
// 전체 도서 목록 조회
public void listBooks() {
if (books.isEmpty()) {
System.out.println("등록된 도서가 없습니다.");
return;
}
books.forEach(System.out::println);
}
// 도서 검색 => 책이름과 저자 항목에 keyword가 포함되어 있는지 검색
public void searchBooks(String keyword) {
keyword = keyword.trim().toLowerCase();
boolean found = false;
for (Book book : books) {
if (book.getTitle().trim().toLowerCase().contains(keyword) ||
book.getAuthor().trim().toLowerCase().contains(keyword)) {
System.out.println(book);
bookViews.put(book.getIsbn(), bookViews.get(book.getIsbn()) + 1);
found = true;
}
}
if (!found) {
System.out.printf("%s를 포함하는 도서가 없습니다.\n", keyword);
}
}
// 도서 삭제
public void deleteBook(String isbn) {
Iterator<Book> iterator = books.iterator();
while (iterator.hasNext()) {
Book book = iterator.next();
if (book.getIsbn().equals(isbn)) {
iterator.remove();
isbnSet.remove(isbn);
bookViews.remove(isbn);
System.out.printf("ISBN %s 책을 삭제했습니다.\n", isbn);
return;
}
}
System.out.printf("ISBN %s와 일치하는 도서를 찾을 수 없습니다.\n", isbn);
}
// 인기 도서 조회
public void mostViewedBooks() {
int maxViews = Collections.max(bookViews.values());
if (bookViews.isEmpty() || maxViews == 0) {
System.out.println("등록된 인기 도서가 없습니다.");
return;
}
for (Map.Entry<String, Integer> entry : bookViews.entrySet()) {
if (entry.getValue() == maxViews) {
books.stream()
.filter(book -> book.getIsbn().equals(entry.getKey()))
.forEach(System.out::println);
}
}
}
}
(실행)
public class Main {
public static void main(String[] args) {
LibraryManagement library = new LibraryManagement();
Book book1 = new Book("12345", "Java Programming", "John", 2020);
Book book2 = new Book("67890", "Python Programming", "Jom", 2024);
Book book3 = new Book("88888", "C++ Programming", "Jane", 2000);
library.listBooks(); // 등록된 도서가 없습니다.
library.addBook(book1);
library.addBook(book1); // ISBN 12345과 동일한 도서가 이미 등록되어 있습니다.
library.addBook(book2);
library.addBook(book3);
library.listBooks();
System.out.println(">>>>");
library.mostViewedBooks(); // 등록된 인기 도서가 없습니다.
library.searchBooks("programming");
library.searchBooks("Java");
library.searchBooks("Mybook"); // mybook를 포함하는 도서가 없습니다.
System.out.println(">>>>");
library.mostViewedBooks();
library.deleteBook("99999"); // ISBN 99999와 일치하는 도서를 찾을 수 없습니다.
library.deleteBook("88888"); // ISBN 88888 책을 삭제했습니다.
library.listBooks();
}
}
import java.util.*;
public class LibraryManagement {
// 도서 정보
private List<Book> books = new ArrayList<>();
// ISBN => 도서 등록 시 동일 도서가 존재하는지 확인
private Set<String> isbnSet = new HashSet<>();
// 조회수 => ISBN, 조회수 정보를 관리
private Map<String, Integer> bookViews = new HashMap<>();
// 도서 등록
public void addBook(Scanner scanner) {
System.out.print("ISBN: ");
String isbn = scanner.nextLine();
if (isbnSet.contains(isbn)) {
System.out.printf("ISBN %s과 동일한 도서가 이미 등록되어 있습니다.\n", isbn);
return;
}
System.out.print("제목: ");
String title = scanner.nextLine();
System.out.print("저자: ");
String author = scanner.nextLine();
System.out.print("년도: ");
int year = scanner.nextInt();
scanner.nextLine();
Book book = new Book(isbn, title, author, year);
books.add(book);
isbnSet.add(book.getIsbn());
bookViews.put(book.getIsbn(), 0);
System.out.println("정상적으로 등록되었습니다." + book);
}
// 전체 도서 목록 조회
public void listBooks() {
if (books.isEmpty()) {
System.out.println("등록된 도서가 없습니다.");
return;
}
books.forEach(System.out::println);
}
// 도서 검색 => 책이름과 저자 항목에 keyword가 포함되어 있는지 검색
public void searchBooks(Scanner scanner) {
System.out.print("검색어를 입력하세요: ");
String keyword = scanner.nextLine();
keyword = keyword.trim().toLowerCase();
boolean found = false;
for (Book book : books) {
if (book.getTitle().trim().toLowerCase().contains(keyword) ||
book.getAuthor().trim().toLowerCase().contains(keyword)) {
System.out.println(book);
bookViews.put(book.getIsbn(), bookViews.get(book.getIsbn()) + 1);
found = true;
}
}
if (!found) {
System.out.printf("%s를 포함하는 도서가 없습니다.\n", keyword);
}
}
// 도서 삭제
public void deleteBook(Scanner scanner) {
System.out.print("삭제할 도서의 ISBN을 입력하세요: ");
String isbn = scanner.nextLine();
Iterator<Book> iterator = books.iterator();
while (iterator.hasNext()) {
Book book = iterator.next();
if (book.getIsbn().equals(isbn)) {
iterator.remove();
isbnSet.remove(isbn);
bookViews.remove(isbn);
System.out.printf("ISBN %s 책을 삭제했습니다.\n", isbn);
return;
}
}
System.out.printf("ISBN %s와 일치하는 도서를 찾을 수 없습니다.\n", isbn);
}
// 인기 도서 조회
public void mostViewedBooks() {
int maxViews = Collections.max(bookViews.values());
if (bookViews.isEmpty() || maxViews == 0) {
System.out.println("등록된 인기 도서가 없습니다.");
return;
}
for (Map.Entry<String, Integer> entry : bookViews.entrySet()) {
if (entry.getValue() == maxViews) {
books.stream()
.filter(book -> book.getIsbn().equals(entry.getKey()))
.forEach(System.out::println);
}
}
}
}
import java.util.Scanner;
public class Main {
public static void printMenu() {
System.out.println("\n도서 관리: ");
System.out.println("1. 도서 등록");
System.out.println("2. 전체 도서 출력");
System.out.println("3. 도서 검색");
System.out.println("4. 도서 삭제");
System.out.println("5. 인기 도서 조회");
System.out.println("6. 종료");
System.out.print("메뉴를 선택하세요: ");
}
public static void main(String[] args) {
LibraryManagement library = new LibraryManagement();
Scanner scanner = new Scanner(System.in);
while(true) {
printMenu();
int choice = scanner.nextInt();
scanner.nextLine();
switch(choice) {
case 1:
library.addBook(scanner);
break;
case 2:
library.listBooks();
break;
case 3:
library.searchBooks(scanner);
break;
case 4:
library.deleteBook(scanner);
break;
case 5:
library.mostViewedBooks();
break;
case 6:
System.out.println("프로그램을 종료합니다.");
scanner.close();
return;
default:
System.out.println("잘못된 입력입니다.");
}
}
}
}
개인별로 데이터를 관리하는 CLI 기반의 애플리케이션을 작성하고, 조별로 통합해서 제공
Diary 만들었다 ㅎㅎ 귀욥게 ,,
import java.util.*;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
@AllArgsConstructor
@Getter
@ToString
class Diary {
private Long id;
private String title;
private int weather;
private int mood;
private String contents;
// Weather와 Mood 이모지 매핑
private static final Map<Integer, String> WEATHER_EMOJIS = Map.of(
1, "☀️",
2, "🌥️",
3, "☁️️",
4, "☔️",
5, "☃️"
);
private static final Map<Integer, String> MOOD_EMOJIS = Map.of(
1, "😡",
2, "😭",
3, "🧐",
4, "😊",
5, "😍"
);
// 이모지 반환 메서드
public String getWeatherEmoji() {
return WEATHER_EMOJIS.getOrDefault(weather, "❓");
}
public String getMoodEmoji() {
return MOOD_EMOJIS.getOrDefault(mood, "❓");
}
// 특정 weather와 mood에 대한 이모지 반환
public static String getWeatherEmojiByValue(int weather) {
return WEATHER_EMOJIS.getOrDefault(weather, "❓");
}
public static String getMoodEmojiByValue(int mood) {
return MOOD_EMOJIS.getOrDefault(mood, "❓");
}
@Override
public String toString() {
return String.format(
"===========================\n" +
"📓 %d번째 일기\n" +
"📝 제목: %s\n" +
"🌤️ 날씨: %s\n" +
"😊 기분: %s\n" +
"🖋️ 내용: %s\n" +
"===========================",
id, title, getWeatherEmoji(), getMoodEmoji(), contents
);
}
}
class DiaryManagement {
// 일기 정보
private final List<Diary> diaries = new ArrayList<>();
// 조회수 => ID, 조회수 정보를 관리
private final Map<Long, Integer> diaryViews = new HashMap<>();
private long nextId = 1;
// 도서 등록
public void addDiary(Scanner scanner) {
Long id = nextId++;
System.out.print("제목을 알려주세요 ✨ ");
String title = scanner.nextLine();
int weather = 0;
while (true) {
try {
System.out.print("오늘 날씨는 어땠나요? 1 ~ 5 중에서 입력해주세요! (1: ☀️, 2: 🌥️, 3: ☁️️, 4: ☔️, 5: ☃️) ");
weather = Integer.parseInt(scanner.nextLine().trim());
if (weather < 1 || weather > 5) {
throw new IllegalArgumentException("1부터 5 사이의 숫자를 입력해주세요.");
}
break;
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해주세요!");
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
int mood = 0;
while (true) {
try {
System.out.print("오늘의 기분을 1 ~ 5 중에서 입력해주세요! (1: 😡, 2: 😭, 3: 🧐, 4: 😊, 5: 😍) ");
mood = Integer.parseInt(scanner.nextLine().trim());
if (mood < 1 || mood > 5) {
throw new IllegalArgumentException("1부터 5 사이의 숫자를 입력해주세요.");
}
break;
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해주세요!");
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
System.out.print("내용을 채워주세요 🍀 ");
String contents = scanner.nextLine();
Diary diary = new Diary(id, title, weather, mood, contents);
diaries.add(diary);
diaryViews.put(diary.getId(), 0);
System.out.println("\n\n\n오늘의 일기 ʕ•ᴥ•ʔ\n" + diary);
}
// 전체 일기 목록 조회
public void listDiaries() {
if (diaries.isEmpty()) {
System.out.println("\n등록된 일기가 없습니다.");
return;
}
diaries.forEach(System.out::println);
}
// 일기 검색 => 일기 제목과 내용에 keyword가 포함되어 있는지 검색
public void searchDiaries(Scanner scanner) {
System.out.print("제목이나 내용을 입력하세요: ");
String keyword = scanner.nextLine();
keyword = keyword.trim().toLowerCase();
boolean found = false;
for (Diary diary : diaries) {
if (diary.getTitle().trim().toLowerCase().contains(keyword) ||
diary.getContents().trim().toLowerCase().contains(keyword)) {
System.out.println(diary);
diaryViews.put(diary.getId(), diaryViews.get(diary.getId()) + 1);
found = true;
}
}
if (!found) {
System.out.printf("\n%s을(를) 포함하는 일기가 없습니다.\n", keyword);
}
}
// weather로 일기 검색
public void searchDiariesByWeather(Scanner scanner) {
int weather = 0;
// 잘못된 입력에 대한 반복 처리
while (true) {
try {
System.out.print("검색할 날씨를 1 ~ 5 중에서 입력해주세요! (1: ☀️, 2: 🌥️, 3: ☁️️, 4: ☔️, 5: ☃️) ");
weather = Integer.parseInt(scanner.nextLine().trim());
if (weather < 1 || weather > 5) {
throw new IllegalArgumentException("1부터 5 사이의 숫자를 입력해주세요.");
}
break;
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해주세요!");
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
// weather 값에 해당하는 이모지 가져오기
String weatherEmoji = Diary.getWeatherEmojiByValue(weather);
// weather 값 필터링
int finalWeather = weather;
List<Diary> filteredDiaries = diaries.stream()
.filter(diary -> diary.getWeather() == finalWeather)
.collect(Collectors.toList());
if (filteredDiaries.isEmpty()) {
System.out.printf("\n%s 날씨에 해당하는 일기가 없습니다.\n", weatherEmoji);
return;
}
System.out.printf("\n%s 날씨에 해당하는 일기 목록입니다 ⭐️📎\n", weatherEmoji);
filteredDiaries.forEach(System.out::println);
}
// mood로 일기 검색
public void searchDiariesByMood(Scanner scanner) {
int mood = 0;
// 잘못된 입력에 대한 반복 처리
while (true) {
try {
System.out.print("검색할 기분을 1 ~ 5 중에서 입력해주세요! (1: 😡, 2: 😭, 3: 🧐, 4: 😊, 5: 😍) ");
mood = Integer.parseInt(scanner.nextLine().trim());
if (mood < 1 || mood > 5) {
throw new IllegalArgumentException("1부터 5 사이의 숫자를 입력해주세요.");
}
break;
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해주세요!");
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
// mood 값에 해당하는 이모지 가져오기
String moodEmoji = Diary.getMoodEmojiByValue(mood);
// mood 값 필터링
int finalMood = mood;
List<Diary> filteredDiaries = diaries.stream()
.filter(diary -> diary.getMood() == finalMood)
.collect(Collectors.toList());
if (filteredDiaries.isEmpty()) {
System.out.printf("\n%s 기분에 해당하는 일기가 없습니다.\n", moodEmoji);
return;
}
System.out.printf("\n%s 기분에 해당하는 일기 목록입니다 ⭐️📎\n", moodEmoji);
filteredDiaries.forEach(System.out::println);
}
// 일기 삭제
public void deleteDiary(Scanner scanner) {
System.out.print("\n삭제할 일기의 번호를 입력하세요: ");
Long id = Long.valueOf(scanner.nextLine());
Iterator<Diary> iterator = diaries.iterator();
while (iterator.hasNext()) {
Diary diary = iterator.next();
if (diary.getId().equals(id)) {
iterator.remove();
diaryViews.remove(id);
System.out.printf("\n%s번째 일기를 삭제했습니다.\n", id);
return;
}
}
System.out.printf("\n%s번째 일기를 찾을 수 없습니다.\n", id);
}
// 조회수가 높은 일기 조회
public void mostViewedDiaries() {
if (diaryViews.isEmpty()) {
System.out.println("\n등록된 일기가 없습니다.");
return;
}
// 조회수가 가장 높은 값 구하기
int maxViews = diaryViews.values().stream()
.max(Integer::compareTo)
.orElse(0);
if (maxViews == 0) {
System.out.println("\n조회수가 높은 일기가 없습니다.");
return;
}
// 조회수가 가장 높은 일기를 필터링
System.out.println("\n조회수가 가장 높은 일기 목록입니다 🩷️📎\n");
diaries.stream()
.filter(diary -> diaryViews.get(diary.getId()) == maxViews)
.forEach(System.out::println);
}
}
public class Suyeon {
public void printMenu() {
System.out.println("\n🩷🔑♥*♡+:。.。.。:+♡*♥ My Diary ♥*♡+:。.。.。:+♡*♥📎📔\n");
System.out.println("1. 일기를 작성해 보아요 ✏️");
System.out.println("2. 모든 일기를 보고싶다면 👀");
System.out.println("3. 제목과 내용으로 검색해 보아요 📝🔎");
System.out.println("4. 날씨로 검색해 보아요 🌈🔎");
System.out.println("5. 기분으로 검색해 보아요 😃🔎");
System.out.println("6. 지우고 싶은 일기가 있어요 🗑️");
System.out.println("7. 어떤 일기를 가장 많이 봤을까? 🧐❓");
System.out.println("8. 일기장 오늘은 이만 덮을게요. 다음에 또 봐요 !! 👋🌌");
System.out.print("\n원하시는 메뉴를 숫자로 입력해 주세요 🪄✨ ");
}
public void diaryApp(Scanner scanner) {
DiaryManagement bookcase = new DiaryManagement();
while(true) {
printMenu();
try {
int choice = Integer.parseInt(scanner.nextLine().trim());
switch(choice) {
case 1:
bookcase.addDiary(scanner);
break;
case 2:
bookcase.listDiaries();
break;
case 3:
bookcase.searchDiaries(scanner);
break;
case 4:
bookcase.searchDiariesByWeather(scanner);
break;
case 5:
bookcase.searchDiariesByMood(scanner);
break;
case 6:
bookcase.deleteDiary(scanner);
break;
case 7:
bookcase.mostViewedDiaries();
break;
case 8:
System.out.println("\n\n\nGood Bye 。.. 💌 .°⑅ପ₍ᐢ。•༝•。ᐢ₎ଓ⑅°.");
return;
default:
System.out.println("\n\n\n1 ~ 8 중에서 입력해주세요! .°⑅ପ₍ᐢ。•༝•。ᐢ₎ଓ⑅°.");
}
} catch (NumberFormatException e) {
System.out.println("\n\n\n숫자를 입력해주세요! .°⑅ପ₍ᐢ。•༝•。ᐢ₎ଓ⑅°.");
}
}
}
}
난 자바도 프론트처럼 해 ,,,, .°⑅ପ₍ᐢ。•༝•。ᐢ₎ଓ⑅°.