Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new lazy #2

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 48 additions & 35 deletions lazy/src/main/java/com/arjenzhou/kit/lazy/Lazy.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.arjenzhou.kit.lazy;

import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
Expand All @@ -10,22 +13,37 @@
* @author [email protected]
* @since 2023/7/8
*/
public interface Lazy<T> extends Supplier<T> {
/**
* set value for Lazy
*
* @param value hold by Lazy
*/
void set(T value);
public final class Lazy<T> implements Supplier<T> {
private transient Supplier<T> supplier;
private volatile T value;

/**
* @param <T> value type hold by Lazy
* @return construct a virtual node
*/
static <T> Lazy<T> unset() {
return of(() -> {
throw new UnsetException();
});
private Lazy(Supplier<T> supplier) {
this.supplier = Objects.requireNonNull(supplier);
}

@Override
public T get() {
if (value == null) {
synchronized (this) {
if (value == null) {
value = Objects.requireNonNull(supplier.get());
supplier = null;
}
}
}
return value;
}

public <R> Lazy<R> map(Function<T, R> mapper) {
return new Lazy<>(() -> mapper.apply(this.get()));
}

public <R> Lazy<R> flatMap(Function<T, Lazy<R>> mapper) {
return new Lazy<>(() -> mapper.apply(this.get()).get());
}

public Lazy<Optional<T>> filter(Predicate<T> predicate) {
return new Lazy<>(() -> Optional.of(get()).filter(predicate));
}

/**
Expand All @@ -35,23 +53,8 @@ static <T> Lazy<T> unset() {
* @param <T> type of value hold by Lazy
* @return new Lazy evaluation
*/
static <T> Lazy<T> of(Supplier<T> supplier) {
return new Lazy<>() {
T cache;

@Override
public void set(T value) {
cache = value;
}

@Override
public T get() {
if (cache == null) {
cache = supplier.get();
}
return cache;
}
};
public static <T> Lazy<T> of(Supplier<T> supplier) {
return new Lazy<>(supplier);
}

/**
Expand All @@ -63,7 +66,7 @@ public T get() {
* @param <E> type of result
* @return new Lazy evaluation
*/
static <T, E> Lazy<E> of(Supplier<T> supplier, Function<T, E> function) {
public static <T, E> Lazy<E> of(Supplier<T> supplier, Function<T, E> function) {
return of(() -> function.apply(supplier.get()));
}

Expand All @@ -78,7 +81,7 @@ static <T, E> Lazy<E> of(Supplier<T> supplier, Function<T, E> function) {
* @param <T> type of result
* @return new Lazy evaluation
*/
static <U, V, T> Lazy<T> of(Supplier<U> s1, Supplier<V> s2, BiFunction<U, V, T> function) {
public static <U, V, T> Lazy<T> of(Supplier<U> s1, Supplier<V> s2, BiFunction<U, V, T> function) {
return of(() -> function.apply(s1.get(), s2.get()));
}

Expand All @@ -98,4 +101,14 @@ static <U, V, T> Lazy<T> of(Supplier<U> s1, Supplier<V> s2, BiFunction<U, V, T>
static <U, V, W, T> Lazy<T> of(Supplier<U> s1, Supplier<V> s2, Supplier<W> s3, TriFunction<U, V, W, T> function) {
return of(() -> function.apply(s1.get(), s2.get(), s3.get()));
}
}

/**
* @param <T> value type hold by Lazy
* @return construct a virtual node
*/
public static <T> Lazy<T> unset() {
return of(()-> {
throw new UnsetException();
});
}
}
Loading