요구사항 1 - Optional을 활용해 조건에 따른 반환
nextstep.optional.User의 ageIsInRange1() 메소드는 30살 이상, 45살 이하에 해당하는 User가 존재하는 경우 true를 반환하는 메소드이다.
같은 기능을 Optional을 활용해 ageIsInRange2() 메소드에 구현한다. 메소드 인자로 받은 User를 Optional로 생성하면 stream의 map, filter와 같은 메소드를 사용하는 것이 가능하다.
nextstep.optional.UserTest의 테스트가 모두 pass해야 한다.
힌트
- Guide To Java 8 Optional 문서를 참고해 Optional 사용 방법을 익힌다.
- Optional.ofNullable(user)을 활용해 User을 Optional로 생성하는 것이 가능하다.
- Optional의 map(), filter() 메소드등을 활용해 필요한 데이터를 추출
- Optional의 isPresent() 메소드 활용
[변경 전]
public static boolean ageIsInRange1(User user) {
boolean isInRange = false;
if (user != null && user.getAge() != null
&& (user.getAge() >= 30
&& user.getAge() <= 45)) {
isInRange = true;
}
return isInRange;
}
[변경 후]
public static boolean ageIsInRange2(User user) {
Optional<User> user1 = Optional.ofNullable(user);
return user1.map(user2 -> user2.getAge())
.filter(age -> age > 30)
.filter(age -> age < 45)
.isPresent();
}
요구사항 2 - Optional에서 값을 반환
nextstep.optional.Users의 getUser() 메소드를 자바 8의 stream과 Optional을 활용해 구현한다.
자바 8의 stream과 Optional을 사용하도록 리팩토링한 후 UsersTest의 단위 테스트가 통과해야 한다.
힌트
- Guide To Java 8 Optional 문서를 참고해 Optional 사용 방법을 익힌다.
- Optional의 orElse() 메소드 활용해 구현한다.
public class Users {
static final User DEFAULT_USER = new User("codesquad", 100);
List<User> users = Arrays.asList(
new User("crong", 35),
new User("pobi", 30),
new User("jk", 40),
new User("honux", 45));
User getUser(String name) {
for (User user : users) {
if (user.matchName(name)) {
return user;
}
}
return DEFAULT_USER;
}
}
public class Users {
static final User DEFAULT_USER = new User("codesquad", 100);
List<User> users = Arrays.asList(
new User("crong", 35),
new User("pobi", 30),
new User("jk", 40),
new User("honux", 45));
User getUser(String name) {
return users.stream()
.filter(user -> user.matchName(name))
.findFirst()
.orElse(DEFAULT_USER);
}
}
요구사항 3 - Optional에서 exception 처리
nextstep.optional.ExpressionTest의 테스트가 통과하도록 Expression의 of 메소드를 구현한다.
단, of 메소드를 구현할 때 자바 8의 stream을 기반으로 구현한다.
힌트
- Guide To Java 8 Optional 문서를 참고해 Optional 사용 방법을 익힌다.
- 자바의 enum 전체 값은 values() 메소드를 통해 배열로 접근 가능하다.
- Arrays.stream()을 이용해 배열을 stream으로 생성할 수 있다.
- 일치하는 값 하나를 추출할 때 findFirst() 메소드를 활용 가능하다.
- Optional의 orElseThrow() 메소드 활용해 구현한다.
ExpressionTest
package nextstep.optional;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
public class ExpressionTest {
@Test
public void of() {
assertThat(Expression.PLUS == Expression.of("+")).isTrue();
}
@Test
public void notValidExpression() {
assertThatIllegalArgumentException()
.isThrownBy(() -> {
Expression.of("&");
});
}
}
[변경 전]
enum Expression {
PLUS("+"), MINUS("-"), TIMES("*"), DIVIDE("/");
private String expression;
Expression(String expression) {
this.expression = expression;
}
private static boolean matchExpression(Expression e, String expression) {
return expression.equals(e.expression);
}
static Expression of(String expression) {
for (Expression v : values()) {
if (matchExpression(v, expression)) {
return v;
}
}
throw new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression));
}
}
[변경 후]
enum Expression {
PLUS("+"), MINUS("-"), TIMES("*"), DIVIDE("/");
private String expression;
Expression(String expression) {
this.expression = expression;
}
private static boolean matchExpression(Expression e, String expression) {
return expression.equals(e.expression);
}
static Expression of(String expression) {
return Arrays.stream(values())
.filter(expression1 -> matchExpression(expression1, expression))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression)));
}
}
'강의 > TDD, Clean Code with Java 12기' 카테고리의 다른 글
엘레강트 오브젝트 (0) | 2021.09.07 |
---|---|
자동차 게임 프로젝트 - 강의 정리 (0) | 2021.09.03 |
스트림 실습 (0) | 2021.08.25 |
스트림(stream) (0) | 2021.08.25 |
람다 실습 2 - 람다를 활용해 중복 제거 (0) | 2021.08.25 |