programing

Java에서 null이 아닌 첫 번째 값을 얻는 방법은 무엇입니까?

sourcetip 2022. 7. 14. 23:22
반응형

Java에서 null이 아닌 첫 번째 값을 얻는 방법은 무엇입니까?

SQL과 동등한 Java가 있습니까?COALESCE기능하고 있습니까?즉, 여러 변수의 첫 번째 null 이외의 값을 반환하는 방법이 있습니까?

예.

Double a = null;
Double b = 4.4;
Double c = null;

어떻게 해서든 첫 번째 null이 아닌 값을 반환하는 스테이트먼트를 갖고 싶다.a,b,그리고.c- 이 경우, 그것은 다시 돌아올 것이다.b, 또는 4.4 (sql 메서드 - return과 같은 것)COALESCE(a,b,c))는 다음과 같은 방법으로 명시적으로 실행할 수 있다는 것을 알고 있습니다.

return a != null ? a : (b != null ? b : c)

하지만, 이것을 실현하기 위해서, 내장된, 받아들여지는 기능은 없을까 하고 생각했습니다.

Apache Commons Lang 3

ObjectUtils.firstNonNull(T...)

Java 8 스트림

Stream.of(T...).filter(Objects::nonNull).findFirst().orElse(null)

아니, 없어.

가장 가까운 것은 다음과 같습니다.

public static <T> T coalesce(T ...items) {
    for(T i : items) if(i != null) return i;
    return null;
}

효율적인 이유로 일반적인 케이스는 다음과 같이 처리할 수 있습니다.

public static <T> T coalesce(T a, T b) {
    return a == null ? b : a;
}
public static <T> T coalesce(T a, T b, T c) {
    return a != null ? a : (b != null ? b : c);
}
public static <T> T coalesce(T a, T b, T c, T d) {
    return ...
}

확인할 변수가 두 개뿐이고 Guava를 사용하는 경우 MoreObjects를 사용할 수 있습니다.first Non Null(첫 번째, 두 번째).

테스트할 참조가 2개뿐이고 Java 8을 사용하는 경우

Object o = null;
Object p = "p";
Object r = Optional.ofNullable( o ).orElse( p );
System.out.println( r );   // p

static을 Import할 경우 표현도 나쁘지 않습니다.

안타깝게도 Optional-method에서는 "몇 가지 변수"를 사용할 수 없습니다.대신 다음을 사용할 수 있습니다.

Object o = null;
Object p = null;
Object q = "p";

Optional<Object> r = Stream.of( o, p, q ).filter( Objects::nonNull ).findFirst();
System.out.println( r.orElse(null) );   // p

LES2의 답변에 따라 오버로드된 함수를 호출하여 효율적인 버전에서 일부 반복을 제거할 수 있습니다.

public static <T> T coalesce(T a, T b) {
    return a != null ? a : b;
}
public static <T> T coalesce(T a, T b, T c) {
    return a != null ? a : coalesce(b,c);
}
public static <T> T coalesce(T a, T b, T c, T d) {
    return a != null ? a : coalesce(b,c,d);
}
public static <T> T coalesce(T a, T b, T c, T d, T e) {
    return a != null ? a : coalesce(b,c,d,e);
}

이 상황에서는 프리프로세서가 필요합니다.null 값이 아닌 첫 번째 값을 선택하는 함수(static 메서드)를 쓰면 모든 항목이 평가되기 때문입니다.일부 항목이 메서드 호출일 경우 문제가 됩니다(시간이 많이 걸리는 메서드 호출일 수 있습니다).그리고 이 메서드는 앞의 항목이 null이 아니더라도 호출됩니다.

일부 기능은 다음과 같습니다.

public static <T> T coalesce(T ...items) …

사용되어야 하지만 바이트 코드로 컴파일하기 전에 이 "합집함수"의 사용법을 찾아 다음과 같은 구성으로 대체하는 프리프로세서가 있어야 합니다.

a != null ? a : (b != null ? b : c)

업데이트 2014-09-02:

Java 8과 Lambdas 덕분에 Java에서 진정한 결합이 가능해졌습니다!중요한 기능 포함: 특정 표현식은 필요할 때만 평가됩니다.이전 표현식이 늘이 아닌 경우 다음 표현식은 평가되지 않습니다(메서드가 호출되지 않거나 계산되거나 디스크/네트워크 작업이 수행되지 않음).

저는 Java 8: couldalesce hledame ne NULové hodnoty – (체코어로 작성되었지만 코드 예는 모두가 이해할 수 있기를 바랍니다.)라는 기사를 썼습니다.

다음과 같이 시험해 보십시오.

public static <T> T coalesce(T... t) {
    return Stream.of(t).filter(Objects::nonNull).findFirst().orElse(null);
}

이 응답을 바탕으로

Guava를 사용하면 다음 작업을 수행할 수 있습니다.

Optional.fromNullable(a).or(b);

NPE가 a ★★★★★★★★★★★★★★★★★」bnull.

편집: 제가 틀렸어요. NPE를 던집니다.Michal Chizmazia가 말한 올바른 방법은 다음과 같습니다.

Optional.fromNullable(a).or(Optional.fromNullable(b)).orNull();

완성도를 높이기 위해 "몇 가지 변수" 사례는 우아하지는 않지만 실제로 가능합니다.들어 변수 ''의 '''가 .o,p , , , , 입니다.q:

Optional.ofNullable( o ).orElseGet(()-> Optional.ofNullable( p ).orElseGet(()-> q ) )

의 사용에 주의해 주십시오.orElseGet()을 들다o,p , , , , 입니다.q변수가 아니라 비용이 많이 들거나 원치 않는 부작용이 있는 식입니다.

인 경우입니다.coalesce(e[1],e[2],e[3],...,e[N])

coalesce-expression(i) ==  e[i]  when i = N
coalesce-expression(i) ==  Optional.ofNullable( e[i] ).orElseGet(()-> coalesce-expression(i+1) )  when i < N

이로 인해 지나치게 긴 식이 생성될 수 있습니다.하지만, 만약 우리가 이 세상으로부터 벗어나려고 한다면null , , , 「 」v[i] 타입이 되어 있을 것이다.Optional<String>하게 ""가 ""입니다String이경은

result= o.orElse(p.orElse(q.get())) ;

또는 표현의 경우:

result= o.orElseGet(()-> p.orElseGet(()-> q.get() ) ) ;

도 '다 하다'는 식으로 넘어갈 수 있어요.o,p , , , , 입니다.q종류여야 한다Supplier<String>같이 말합니다.

Supplier<String> q= ()-> q-expr ;
Supplier<String> p= ()-> Optional.ofNullable(p-expr).orElseGet( q ) ;
Supplier<String> o= ()-> Optional.ofNullable(o-expr).orElseGet( p ) ;

나서 coalesce o.get().

보다 구체적인 예를 들자면:

Supplier<Integer> hardcodedDefaultAge= ()-> 99 ;
Supplier<Integer> defaultAge= ()-> defaultAgeFromDatabase().orElseGet( hardcodedDefaultAge ) ;
Supplier<Integer> ageInStore= ()-> ageFromDatabase(memberId).orElseGet( defaultAge ) ;
Supplier<Integer> effectiveAge= ()-> ageFromInput().orElseGet( ageInStore ) ;

defaultAgeFromDatabase(),ageFromDatabase() , , , , 입니다.ageFromInput() Optional<Integer>★★★★★★★★★★★★★★★★★★.

그리고 그 다음에coalesce becomes가 되다effectiveAge.get() 간단히 말해서effectiveAge에 들면Supplier<Integer>.

IMHO, Java 8을 사용하면 점점 더 많은 코드가 이렇게 구조화됩니다. 이는 매우 자기설명적인 동시에 효율적이기 때문입니다. 특히 더 복잡한 경우에는 더욱 그렇습니다.

Lazy<T>를를okesokesokesokesokes를 Supplier<T>한 번, 느긋하게, '일관성', '일관성', '일관성'의 이 있다.Optional<T> (예:)Optional<T>-Optional<T>operators, 「」의 경우도 .Supplier<Optional<T>>를 참조해 주세요.

비싼 방법의 평가를 피하고 싶을 때는 공급업체를 이용하는 것은 어떻습니까?

다음과 같이 합니다.

public static <T> T coalesce(Supplier<T>... items) {
for (Supplier<T> item : items) {
    T value = item.get();
    if (value != null) {
        return value;
    }
    return null;
}

그리고 나서 이렇게 사용해요.

Double amount = coalesce(order::firstAmount, order::secondAmount, order::thirdAmount)

2개, 3개 또는4개의 인수를 사용하여 오버로드된 메서드를 콜에 사용할 수도 있습니다.

또한 다음과 같은 스트림도 사용할 수 있습니다.

public static <T> T coalesce2(Supplier<T>... s) {
    return Arrays.stream(s).map(Supplier::get).filter(Objects::nonNull).findFirst().orElse(null);
}

되어 있기 에 Java 9가 내장되어 있습니다.Objects.requireNonNullElse두 매개 변수 병합에 대한 메서드입니다.그것이 나에게 가장 유용했다.

그럼 어떻게 해?

firstNonNull = FluentIterable.from(
    Lists.newArrayList( a, b, c, ... ) )
        .firstMatch( Predicates.notNull() )
            .or( someKnownNonNullDefault );

Java Array List는 늘 엔트리를 쉽게 허용하며 이 식은 고려 대상 객체의 수에 관계없이 일관됩니다(이 형식에서는 고려 대상 객체가 모두 같은 유형이어야 합니다).

Object coalesce(Object... objects)
{
    for(Object o : object)
        if(o != null)
            return o;
    return null;
}

언급URL : https://stackoverflow.com/questions/2768054/how-to-get-the-first-non-null-value-in-java

반응형