আপনি ইতিমধ্যে যা করছেন আপনি এটি আরও সংক্ষিপ্ত করতে পারবেন না।
আপনি দাবি করেন যে আপনি চান না .filter(Optional::isPresent)
এবং .map(Optional::get)
।
এটি @ স্টার্টমার্কস বর্ণনা করার পদ্ধতি দ্বারা সমাধান করা হয়েছে, তবে ফলস্বরূপ আপনি এখন এটিকে ম্যাপ করেন Optional<T>
, সুতরাং এখন আপনাকে ব্যবহারের প্রয়োজন এবং শেষ পর্যন্ত .flatMap(this::streamopt)
একটি দরকার get()
।
সুতরাং এটি এখনও দুটি বিবৃতি নিয়ে গঠিত এবং আপনি এখন নতুন পদ্ধতিতে ব্যতিক্রম পেতে পারেন! কারণ, যদি প্রতিটি alচ্ছিক খালি থাকে? তারপরে findFirst()
একটি খালি alচ্ছিকটি ফিরে আসবে এবং আপনার get()
ব্যর্থ হবে!
সুতরাং আপনার যা আছে:
things.stream()
.map(this::resolve)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
হয় আসলে সবচেয়ে ভালো উপায় সম্পন্ন করার জন্য আপনি যা চান তা, এবং যে আপনি একটি যেমন ফলাফলের সংরক্ষণ করতে চান হয় T
একটি হিসেবে নয়, Optional<T>
।
আমি একটি CustomOptional<T>
ক্লাস তৈরির স্বাধীনতা গ্রহণ করেছি যা Optional<T>
একটি অতিরিক্ত পদ্ধতি সরবরাহ করে, এবং flatStream()
। নোট করুন যে আপনি প্রসারিত করতে পারবেন না Optional<T>
:
class CustomOptional<T> {
private final Optional<T> optional;
private CustomOptional() {
this.optional = Optional.empty();
}
private CustomOptional(final T value) {
this.optional = Optional.of(value);
}
private CustomOptional(final Optional<T> optional) {
this.optional = optional;
}
public Optional<T> getOptional() {
return optional;
}
public static <T> CustomOptional<T> empty() {
return new CustomOptional<>();
}
public static <T> CustomOptional<T> of(final T value) {
return new CustomOptional<>(value);
}
public static <T> CustomOptional<T> ofNullable(final T value) {
return (value == null) ? empty() : of(value);
}
public T get() {
return optional.get();
}
public boolean isPresent() {
return optional.isPresent();
}
public void ifPresent(final Consumer<? super T> consumer) {
optional.ifPresent(consumer);
}
public CustomOptional<T> filter(final Predicate<? super T> predicate) {
return new CustomOptional<>(optional.filter(predicate));
}
public <U> CustomOptional<U> map(final Function<? super T, ? extends U> mapper) {
return new CustomOptional<>(optional.map(mapper));
}
public <U> CustomOptional<U> flatMap(final Function<? super T, ? extends CustomOptional<U>> mapper) {
return new CustomOptional<>(optional.flatMap(mapper.andThen(cu -> cu.getOptional())));
}
public T orElse(final T other) {
return optional.orElse(other);
}
public T orElseGet(final Supplier<? extends T> other) {
return optional.orElseGet(other);
}
public <X extends Throwable> T orElseThrow(final Supplier<? extends X> exceptionSuppier) throws X {
return optional.orElseThrow(exceptionSuppier);
}
public Stream<T> flatStream() {
if (!optional.isPresent()) {
return Stream.empty();
}
return Stream.of(get());
}
public T getTOrNull() {
if (!optional.isPresent()) {
return null;
}
return get();
}
@Override
public boolean equals(final Object obj) {
return optional.equals(obj);
}
@Override
public int hashCode() {
return optional.hashCode();
}
@Override
public String toString() {
return optional.toString();
}
}
আপনি দেখতে পাবেন যে আমি flatStream()
এখানে যুক্ত করেছি:
public Stream<T> flatStream() {
if (!optional.isPresent()) {
return Stream.empty();
}
return Stream.of(get());
}
হিসাবে ব্যবহার:
String result = Stream.of("a", "b", "c", "de", "fg", "hij")
.map(this::resolve)
.flatMap(CustomOptional::flatStream)
.findFirst()
.get();
আপনাকে এখনওStream<T>
এখানে ফিরে আসতে হবে , যেমন আপনি ফিরতে পারবেন না T
, কারণ যদি !optional.isPresent()
তাই হয় T == null
তবে আপনি যদি এটির ঘোষণা দেন তবে আপনার প্রবাহে .flatMap(CustomOptional::flatStream)
যুক্ত null
করার চেষ্টা করা হবে এবং এটি সম্ভব নয়।
উদাহরণ স্বরূপ:
public T getTOrNull() {
if (!optional.isPresent()) {
return null;
}
return get();
}
হিসাবে ব্যবহার:
String result = Stream.of("a", "b", "c", "de", "fg", "hij")
.map(this::resolve)
.map(CustomOptional::getTOrNull)
.findFirst()
.get();
NullPointerException
স্ট্রিম ক্রিয়াকলাপগুলির ভিতরে এখন একটি ছোঁড়াবে।
উপসংহার
আপনি যে পদ্ধতিটি ব্যবহার করেছেন, তা আসলে সেরা পদ্ধতি।
.flatMap(Optional::toStream)
দেখতে পাই, এটির উপস্থিতি থাকলে , আপনার সংস্করণ সহ আপনি দেখতে পাচ্ছেন যা চলছে।