자바 에서 optional 사용 에 대한 상세 한 분석
1.옵션 소개
옵션 대상 구축 하기;방법:empty(),of(),of Nullable()
// Optional , null , Optional 。
// : C null
// :<T> C
// : Optional null , Optional
Optional.ofNullable("");
// Optional null 。
// :value C , null
// :<T> C
// : Optional
Optional.of("");
// Optional 。 Optional 。
// :<T> C
// : Optional
//api : , == Optional.empty() 。
// 。
// isPresent()
Optional.empty();
3.optional API 및 소스 코드 주석
package java.util;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
null 。 , isPresent() true 。 , , isPresent() false 。
, orElse() ( , ) ifPresent() ( , )。
; Optional ( ( == ), ) ,
*/
public final class Optional<T> {
/**
* empty()
*/
private static final Optional<?> EMPTY = new Optional<>();
/**
* , ; false。 null,
*/
private final T value;
/**
。
impl :
, VM EMPTY
*/
private Optional() {
this.value = null;
}
/**
Optional 。 Optional 。
:<T> C
: Optional
api :
, == Optional.empty() 。 。 isPresent()
*/
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
/**
。
: C null
:NullPointerException null
*/
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
/**
Optional null 。
:value C , null
:<T> C
: Optiona
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
/**
Optional , null , Optional 。
: C null
:<T> C
: Optional null , Optional
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
/**
, , NoSuchElementException 。
: Optional null
:NoSuchElementException
api : orElseThrow() 。
*/
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
/**
, true , false 。
: , true , false
*/
public boolean isPresent() {
return value != null;
}
/**
, true , false 。
: , true , false
*/
public boolean isEmpty() {
return value == null;
}
/**
, , 。
: C ( )
*/
public void ifPresent(Consumer<? super T> action) {
if (value != null) {
action.accept(value);
}
}
/**
, , 。
: C ( )emptyAction C ( )
:NullPointerException null , null
@since 9
*/
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
if (value != null) {
action.accept(value);
} else {
emptyAction.run();
}
}
/**
, , Optional , Optional 。
: C ( )
: Optional Optional , , Optional
:NullPointerException null
*/
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent()) {
return this;
} else {
return predicate.test(value) ? this : empty();
}
}
/**
, Optional ( by ofNullable ), , Optional 。
null , Optional
*/
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
/**
, Optional -bearing , Optional 。
map(Function) , Optional , , flatMap Optional 。
:mapper C ( )
:<U> C Optional
: Optional Optional , , Optional
:NullPointerException null null
*/
public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
@SuppressWarnings("unchecked")
Optional<U> r = (Optional<U>) mapper.apply(value);
return Objects.requireNonNull(r);
}
}
/**
, Optional , Optional 。
: C Optional
: Optional Optional , , Optional 。
:NullPointerException null null
* @since 9
*/
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
Objects.requireNonNull(supplier);
if (isPresent()) {
return this;
} else {
@SuppressWarnings("unchecked")
Optional<T> r = (Optional<T>) supplier.get();
return Objects.requireNonNull(r);
}
}
/**
, Stream , Stream 。
: Stream
* @since 9
*/
public Stream<T> stream() {
if (!isPresent()) {
return Stream.empty();
} else {
return Stream.of(value);
}
}
/**
, , other 。
: C ( )。 null 。
: ( ), other
*/
public T orElse(T other) {
return value != null ? value : other;
}
/**
, , 。
: C
: ( ),
*/
public T orElseGet(Supplier<? extends T> supplier) {
return value != null ? value : supplier.get();
}
/**
* If a value is present, returns the value, otherwise throws
* {@code NoSuchElementException}.
*
* @return the non-{@code null} value described by this {@code Optional}
* @throws NoSuchElementException if no value is present
* @since 10
*/
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
/**
, , 。
:exceptionSupplier C
:<X> C
: ( )
:X C NullPointerException null
api :
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
}
4.테스트 사용4.1 구축
// Optional , null , Optional 。
// : C null
// :<T> C
// : Optional null , Optional
Optional s1 = Optional.ofNullable(null);
// value null optional , of() null ;
Optional<MyUser> s2 = Optional.of(new MyUser(" 2","123456"));
// value null optional ;
Optional<MyUser> s3 = Optional.ofNullable(null);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
/*
* Optional.empty
* Optional[MyUser{id=' 2', username='123456'}]
* Optional.empty
**/
4.2 판단 류
Optional<MyUser> myUser1 = Optional.empty();
Optional<MyUser> myUser2 = Optional.of(new MyUser(" ", "123456"));
// filter lambda,lambda boolean;true: ,false: optional;
Optional<MyUser> myUser3 = myUser2.filter(user -> " ".equals(user.getUsername()));
// isPresent value null; get , isPresent, value null, get ;
if (myUser1.isPresent()) {
MyUser value = myUser1.get();
System.out.println("optional value:" + value);
} else {
System.out.println("optional value==null");
}
// ifPresent lambda, value!=null , ; value==null , ;
myUser2.ifPresent(value -> System.out.println("optional value:" + value));
System.out.println(myUser3);
// :
//optional value==null
//optional value:MyUser{id=' ', username='123456'}
//Optional.empty
4.3,획득 클래스(상용)
Optional<MyUser> userInfoEmptyOpt = Optional.empty();
Optional<MyUser> userInfoOpt = Optional.of(new MyUser(" ","123456"));
// 1、 , value==null, NoSuchElementException
MyUser userInfo1 = userInfoOpt.get();
// 2、orElse UserInfo ;
// value!=null , value ; value==null , ;
MyUser userInfo2 = userInfoEmptyOpt.orElse(new MyUser(" 1","123456"));
// 3、orElseGet orElse orElseGet lambda ;
// value!=null , value ;
// value==null , lambda ;
MyUser userInfo3 = userInfoEmptyOpt.orElseGet(() -> new MyUser(" 2","123456"));
// 4、orElseThrow lambda ,lambda Exception; value!=null , value ; value==null , ;
MyUser userInfo4 = userInfoOpt.orElseThrow(NullPointerException::new);
System.out.println(userInfo1);
System.out.println(userInfo2);
System.out.println(userInfo3);
System.out.println(userInfo4);
// :
// UserInfo(username= , password=123456)
// UserInfo(username= 1, password=123456)
// UserInfo(username= 2, password=123456)
// UserInfo(username= , password=123456)
4.4 전환 류
Optional<MyUser> userInfoOpt = Optional.of(new MyUser(" ","123456"));
// value UserInfo, map Optional<String>
Optional<String> username = userInfoOpt.map(MyUser::getId);
// map Optional , map Optional<Optional<String>> ; flatMap ;
Optional<Optional<String>> unFlatMap = userInfoOpt.map(user -> Optional.of(user.getId()));
Optional<String> flatMap = userInfoOpt.flatMap(user -> Optional.of(user.getId()));
System.out.println(username);
System.out.println(unFlatMap);
System.out.println(flatMap);
// :
// Optional[ ]
// Optional[Optional[ ]]
// Optional[ ]
4.5,테스트 API 사용
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Optional;
/**
* @version 1.0
* @author: crush
* @date: 2021-04-12 20:51
*/
public class OptionalStudy {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
static class Employee {
private Long id;
private String name;
private Boolean leader;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
static class Leader {
private Long employeeId;
private BigDecimal bonus;
}
/**
* ID 1 , , ;
* @throws
*/
@Test
public void tst() {
Optional<Leader> leader = Optional.ofNullable(getEmployeeById(1L)
.filter(Employee::getLeader)
.map(Employee::getId)
.flatMap(this::getLeaderByEmployeeId)
.orElse(null));
if (leader.isPresent()) {
Optional.of(leader.map(Leader::getBonus).map(bonus -> String.format(" ID 1 leader :%s", bonus)).orElse(" ID 1 leader ")).ifPresent(System.out::println);
} else {
System.out.println(" ID 1 leader , , ");
}
}
private Optional<Employee> getEmployeeById(Long id) {
//return Optional.of(new Employee(1L, " ", Boolean.TRUE));
return Optional.of(new Employee(1L, " ", Boolean.FALSE));
}
private Optional<Leader> getLeaderByEmployeeId(Long employeeId) {
//return employeeId == 1L ? Optional.of(new Leader(1L, BigDecimal.valueOf(1000000000))) : Optional.empty();
return employeeId == 1L ? Optional.of(new Leader(1L, null)) : Optional.empty();
}
}
평소:프로젝트 의 인 스 턴 스:
return Optional.ofNullable(iNewsMapper.selectNewsWithNewsCategoryById(id))
.orElseThrow(() -> new BaseException(DataSourceResponseEnum.SELECT_ERROR));
ofNullable:주어진 값 을 설명 하 는 optional 을 되 돌려 줍 니 다.null 이 아니라면 빈 optional 을 되 돌려 줍 니 다.
orElseThrow
값 이 존재 하면 이 값 을 되 돌려 줍 니 다.그렇지 않 으 면 이상 제공 함수 에 의 한 이상 을 던 집 니 다.
이전의 문법 은:
if(iNewsMapper.selectNewsWithNewsCategoryById(id)==null){
throw new BaseException(DataSourceResponseEnum.SELECT_ERROR);
}
else{
return iNewsMapper.selectNewsWithNewsCategoryById(id);
}
이런 서법 은 비교적 추악 하 다.상술 한 추악 한 서법 을 피하 기 위해 추악 한 디자인 을 우아 하 게 만 들 었 다.JAVA 8 은 이러한 표기 법 을 최적화 하기 위해 옵션 클래스 를 제공 했다.예 2:
Optional<News> news = Optional.ofNullable(iNewsMapper.selectNewsWithNewsCategoryById(id));
news.ifPresent(item -> {
item.setLastId(this.selectLastNewsId(id));
item.setNextId(this.selectNextNewsId(id));
taskExecutor.execute(() -> this.addReadCount(id, ip));
});
return news.orElseThrow(() -> new BaseException(DataSourceResponseEnum.SELECT_ERROR));
블 로 거들 은 자신 이 처음으로 Optional 을 알 게 되 었 는데,이번에 프로젝트 를 볼 때 마침 만 나 서 잘 살 았 다.나의 건 의 는 좋아 하면 쓰 고,싫어 하면 쓰 지 않 는 다 는 것 이다.
사용 하면 좀 더 우아 해 보이 지만 단점 도 뚜렷 하고 논리성 이 뚜렷 하지 않다.
자바 의 새로운 특성 에 대한 optional 의 상세 한 해석 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 의 optional 류 에 관 한 상세 한 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.