Last active
November 5, 2017 14:49
-
-
Save jjangga0214/80ba5be5970ce4170b63f151c3e7635c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.week8; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.stream.Collectors; | |
import io.week8.Library.LibraryBook; | |
public class LibraryDemo { | |
public static void main(String[] args) { | |
// 도서관 객체를 만들고 3개의 책을 비치한다. | |
Library demoLibrary = new Library("demoLibrary"); | |
// 제목이 A인 책을 더함 | |
demoLibrary.addBook(new LibraryBook("A")); | |
// 제목이 B인 책을 더함 | |
demoLibrary.addBook("B"); | |
demoLibrary.addBook(new LibraryBook("C")); | |
demoLibrary.printAllBooks(); | |
demoLibrary.printAllRentedBooks(); | |
// 이름이 A인 책을 모두 빌린다. | |
List<LibraryBook> booksRentedByMeNow = demoLibrary.rentBooks("A"); | |
demoLibrary.printAllBooks(); | |
demoLibrary.printAllRentedBooks(); | |
// 책을 반납한다. | |
// 현재 상황에서는 아래의 2가지 방법이 모두 같은 효과를 지닌다. | |
LibraryBook bookToReturn = booksRentedByMeNow.isEmpty() ? new LibraryBook("A") : booksRentedByMeNow.get(0); | |
// 반납 방법 1 : Book 객체를 직접 넘긴다. | |
demoLibrary.returnRentedBook(bookToReturn); | |
// 반납 방법 2 : book의 이름을 넘긴다. | |
demoLibrary.returnRentedBook("A"); | |
demoLibrary.printAllBooks(); | |
demoLibrary.printAllRentedBooks(); | |
} | |
} | |
class Library { | |
private String name; | |
// 각 도서관 인스턴스에 따라 다른 값을 가지지 않고, 클래스 차원에서 하나의 값을 가지므로 static 으로 선언 | |
public static String hour = "9AM to 5PM"; | |
private LibraryBook[] books; | |
private int nextIndex = 0; | |
// 개인적으로는 도서관마다 책의 권수가 다를 수도 있다고 생각하지만 무조건 10으로 하라길래 인스턴스 변수 대신 상수로 선언했다. | |
public static final int LIBRARY_SIZE = 10; | |
/** | |
* 도서관의 책들을 나타내는 LibraryBook 클래스는 Library의 내부에 내부 클래스로서 선언했다. 내부 클래스로 선언함으로서 | |
* 렌트처리를 Library 클래스 내부에서만 처리 가능하도록 할수 있는 효과가 생긴다. 물론 Book을 상속한 LibraryBook 클래스를 | |
* 내부클래스로 만드는 대신 그냥 Book을 렌트처리 할 수도 있지만, 렌트되었는지 아닌지의 여부를 Book 외부에 놓고 싶지 않고 각 책의 | |
* 속성으로 관리하고 싶어서 자식클래스로 구현했다. 지금 상황에서는 논리적으로 LibraryBook은 각 Library 인스턴스에 종속적인 | |
* 특징은 가지지 않으므로 static 으로 선언했다 | |
*/ | |
public static class LibraryBook extends Book { | |
private boolean isRented = false; | |
// 도서관 내부에서만 | |
public LibraryBook(String name) { | |
super(name); | |
} | |
public boolean isRented() { | |
return isRented; | |
} | |
// 외부에서 반납처리를 할수 없고 오직 Library 클래스 또는 LibraryBook 클래스 안에서만 반납처리 가능하게 private 으로 | |
// 선언한다. | |
private void setRented(boolean isRented) { | |
this.isRented = isRented; | |
} | |
// 논리적으로 super.name 속성으로만 equals를 판단하면 되기 때문에 | |
// 여기서는 hashcode만 재정의하고 equals는 오버라이딩 하지 않고 부모 클래스의 것으로 쓰도록 한다. | |
@Override | |
public int hashCode() { | |
final int prime = 31; | |
int result = 1; | |
result = prime * result + (isRented ? 1231 : 1237); | |
return result; | |
} | |
@Override | |
public String toString() { | |
return "LibraryBook [isRented=" + isRented + ", name=" + getName() + "]"; | |
} | |
} | |
public Library(String name) { | |
this.name = name; | |
this.books = new LibraryBook[LIBRARY_SIZE]; | |
} | |
// 메서드 오버로딩 | |
public void addBook(LibraryBook book) { | |
if (nextIndex < this.books.length) | |
this.books[nextIndex++] = book; | |
} | |
// 메서드 오버로딩 | |
public void addBook(String bookname) { | |
this.addBook(new LibraryBook(bookname)); | |
} | |
public void printAllBooks() { | |
System.out.println("모든 책들 목록입니다."); | |
// System.out.println(Arrays.toString(this.books));// 주석처리된 왼쪽의 방법대로 하면 null도 같이 | |
// 출력된다. | |
Arrays.stream(this.books) // this.books의 스트림[쉽게말해 자료들의 흐름. 리스트와 비슷]을 형성한다. | |
.filter(book -> book != null) // null이 아닌 책들만 필터링한다. | |
.forEach(System.out::println); // 필터링된 책들을 모두 출력한다. | |
} | |
public void printAllRentedBooks() { | |
System.out.println("빌려간 책들 목록입니다. (아래에 아무것도 출력되지 않으면 빌려간 책이 없는 것임)"); | |
Arrays.stream(this.books) // this.books의 스트림[쉽게말해 자료들의 흐름. 리스트와 비슷]을 형성한다. | |
.filter(book -> book != null) // null이 아닌 책들만 필터링한다. | |
.filter(LibraryBook::isRented) // 렌트된 책들만 필터링한다. | |
.forEach(System.out::println); // 필터링된 책들을 모두 출력한다. | |
} | |
public List<LibraryBook> rentBooks(String bookname) { | |
List<LibraryBook> booksToRent = Arrays.stream(this.books) // this.books의 스트림[쉽게말해 자료들의 흐름. 리스트와 비슷]을 형성한다. | |
.filter(book -> book != null) // null이 아닌 책들만 필터링한다. | |
.filter(book -> !book.isRented()) // 렌트되지 않은 책들만 필터링한다. | |
.filter(book -> book.getName().equals(bookname)) // 이름이 bookname과 같은 값인 책들만 필터링한다.. | |
.peek(book -> book.setRented(true)) // 필터링된 책들을 모두 rent 처리한다. | |
.collect(Collectors.toList()); // 필터링된 책들을 List로 묶는다. | |
return booksToRent; | |
} | |
// 메서드 오버로딩 | |
public void returnRentedBook(LibraryBook book) { | |
book.setRented(false); | |
} | |
// 메서드 오버로딩 | |
public void returnRentedBook(String bookname) { | |
Arrays.stream(this.books) // this.books의 스트림[쉽게말해 자료들의 흐름. 리스트와 비슷]을 형성한다. | |
.filter(book -> book != null) // null이 아닌 책들만 필터링한다. | |
.filter(book -> book.getName().equals(bookname)) // 이름이 bookname과 같은 값인 책들만 필터링한다.. | |
.forEach(book -> book.setRented(false)); // 필터링된 책들을 모두 반납 처리한다. | |
} | |
} | |
class Book { | |
private final String name; | |
public Book(String name) { | |
this.name = name; | |
} | |
public String getName() { | |
return name; | |
} | |
@Override | |
public int hashCode() { | |
final int prime = 31; | |
int result = 1; | |
result = prime * result + ((name == null) ? 0 : name.hashCode()); | |
return result; | |
} | |
@Override | |
public boolean equals(Object obj) { | |
if (this == obj) | |
return true; | |
if (obj == null) | |
return false; | |
if (getClass() != obj.getClass()) | |
return false; | |
Book other = (Book) obj; | |
if (name == null) { | |
if (other.name != null) | |
return false; | |
} else if (!name.equals(other.name)) | |
return false; | |
return true; | |
} | |
@Override | |
public String toString() { | |
return "Book [name=" + name + "]"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment