অপশনাল.আইফপ্রেসিড () এর সঠিক ব্যবহার


99

আমি জাভা 8 এপিআইয়ের ifPresent()পদ্ধতিটি বোঝার চেষ্টা করছি Optional

আমার সাধারণ যুক্তি রয়েছে:

Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));

তবে এটি সংকলনের ত্রুটির ফলস্বরূপ:

ifPresent(java.util.functionError:(186, 74) java: 'void' type not allowed here)

অবশ্যই আমি এই জাতীয় কিছু করতে পারি:

if(user.isPresent())
{
  doSomethingWithUser(user.get());
}

তবে এটি ঠিক একটি বিশৃঙ্খল nullচেকের মতো।

আমি যদি কোডটি এতে পরিবর্তন করি:

 user.ifPresent(new Consumer<User>() {
            @Override public void accept(User user) {
                doSomethingWithUser(user.get());
            }
        });

কোডটি অবিচ্ছিন্ন হয়ে উঠছে, যা আমাকে পুরানো চেকটিতে ফিরে যাওয়ার কথা ভাবায় null

কোন ধারনা?

উত্তর:


160

Optional<User>.ifPresent()Consumer<? super User>যুক্তি হিসাবে গ্রহণ করে । আপনি এটিকে এমন একটি বহিঃপ্রকাশ যাচ্ছেন যাঁর ধরণটি বাতিল। সুতরাং যে সংকলন না।

একজন গ্রাহক ল্যাম্বডা এক্সপ্রেশন হিসাবে বাস্তবায়িত করার উদ্দেশ্যে:

Optional<User> user = ...
user.ifPresent(theUser -> doSomethingWithUser(theUser));

বা এমনকি সহজ, একটি পদ্ধতি রেফারেন্স ব্যবহার করে:

Optional<User> user = ...
user.ifPresent(this::doSomethingWithUser);

এটি মূলত একই জিনিস

Optional<User> user = ...
user.ifPresent(new Consumer<User>() {
    @Override
    public void accept(User theUser) {
        doSomethingWithUser(theUser);
    }
});

ধারণাটি হ'ল doSomethingWithUser()যদি ব্যবহারকারী উপস্থিত থাকে তবে পদ্ধতি কলটি কার্যকর করা হবে। আপনার কোডটি পদ্ধতি কলটি সরাসরি চালায় এবং এর অকার্যকর ফলাফলটি পাস করার চেষ্টা করে ifPresent()


4
এই কোডটি বিশৃঙ্খল হয়ে উঠছে .. একটি নাল চেক আরও অনেক ক্লিনার হবে। আপনি কি মনে করেন না বিশেষভাবে যে doSomethingWithUser একটি স্থির পদ্ধতি নয়
রায়মান

4
কোন কোড? আপনার যেটি ব্যবহার করা উচিত তা হ'ল দ্বিতীয়টি, যা দৃষ্টান্তটিকে (অর্থাত্ অ স্থিতিশীল) পদ্ধতি ডুসোমিংথিংথ ব্যবহারকারী () বলে। আমি দেখতে পাচ্ছি না যে এটি কীভাবে বিশৃঙ্খলাবদ্ধ। শেষ কোডটি একটি প্রাক-ল্যাম্বদা বিশ্বে ল্যাম্বদার সমতুল্য আপনাকে ব্যাখ্যা করার জন্য রয়েছে। এটি ব্যবহার করবেন না।
জেবি নিজত

4
হ্যাঁ, তবে আপনি বেনামে ক্লাস করতে অভ্যস্ত হতে পারেন এবং এভাবে বেনাম শ্রেণীর সমতুল্য দেখে ল্যাম্বডা কী করে তা বুঝতে পারেন। এটাই আসল কথা.
জেবি নিজত

4
আপনার সংশোধন করার কিছুই নেই। এটি যেমন রয়েছে তেমন ছেড়ে দিন এবং দ্বিতীয় উদাহরণটি ব্যবহার করুন:user.ifPresent(this::doSomethingWithUser);
জেবি নিজেট

11
@ রায়ম্যান আপনার যদি এমন কোনও ফাংশন থাকে যা এখানে ফিরে আসে Optional<User>তবে প্রায়শই এটি স্থানীয় ভেরিয়েবলে সংরক্ষণের প্রয়োজন হয় না। পদ্ধতিটি কল করে কেবল চেইন করুন:funcThatMightReturnUser().ifPresent(this::doSomethingWithUser);
স্টুয়ার্ট

21

@ জেবিনিজেটের উত্তর ছাড়াও, আমার সাধারণ ব্যবহারের ক্ষেত্রে ifPresentসম্মিলন করা .isPresent()এবং .get():

পুরানো উপায়:

Optional opt = getIntOptional();
if(opt.isPresent()) {
    Integer value = opt.get();
    // do something with value
}

নতুন উপায়:

Optional opt = getIntOptional();
opt.ifPresent(value -> {
    // do something with value
})

এটি আমার কাছে আরও স্বজ্ঞাত।


9

জটিল কোডটি যখন আপনি সহজ করে তুলতে পারেন কেন?

সত্যই, আপনি যদি Optionalক্লাসটি পুরোপুরি ব্যবহার করতে চলেছেন তবে সর্বাধিক সাধারণ কোডটি যা আপনি ইতিমধ্যে লিখেছেন ...

if (user.isPresent())
{
    doSomethingWithUser(user.get());
}

এই কোডটি হওয়ার সুবিধা রয়েছে

  1. পাঠযোগ্য
  2. ডিবাগ করা সহজ (ব্রেকপয়েন্ট)
  3. কৌশল নয়

কেবল ওরাকল Optionalজাভা 8- এ ক্লাস যুক্ত করেছে এর অর্থ এই নয় যে এই শ্রেণিটি অবশ্যই সমস্ত পরিস্থিতিতে ব্যবহার করা উচিত।


4
ইফপ্রেসেন্ট ব্যবহারের সবচেয়ে বড় সুবিধা হ'ল এটি আপনাকে ম্যানুয়ালি কখনও (কল করুন) কল করার প্রয়োজনীয়তা সরিয়ে দেয়। গেট () ম্যানুয়ালি কল করা ত্রুটি প্রবণ, কারণ প্রথমে আইপ্রেসেট চেক করা ভুলে যাওয়া সহজ তবে আপনি যদি ইফপ্রেসড ব্যবহার করেন তবে তা ভুলে যাওয়া আপনার পক্ষে অসম্ভব
ডাস্টিনরোপসচ

4
ঠিক আছে এবং প্রতিবার আপনি 'ব্যবহারকারী' অবজেক্টটি ব্যবহার করবেন আপনাকে .ifPstream () কল করতে হবে। কোডটি দ্রুত অপঠনযোগ্য হয়ে উঠবে কারণ আপনি পড়তে পারবেন।
স্ক্লেব

4
উপর ভুল বানান ফিক্সিংয়ের জন্য আপনার প্রোফাইল পৃষ্ঠায় ( VB.Net , Netbeans , SqlServer , PostgreSQL , মাইএসকিউএল , এবং Linq, আপনি ব্যবহার করতে পারেন আমার সেবা এছাড়া রয়েছে। একটি সংশ্লিষ্ট wordlist
পিটার মর্টেনসেন

7

ফ্ল্যাটম্যাপ ব্যবহার করুন। যদি কোনও মান উপস্থিত থাকে তবে ফ্ল্যাটম্যাপ কেবলমাত্র সেই মানটি সহ একটি অনুক্রমিক স্ট্রিম প্রদান করে, অন্যথায় একটি খালি স্ট্রিম প্রদান করে। সুতরাং ব্যবহার করার দরকার নেই ifPresent()। উদাহরণ:

list.stream().map(data -> data.getSomeValue).map(this::getOptinalValue).flatMap(Optional::stream).collect(Collectors.toList());

4
ঐচ্ছিক :: প্রবাহ java9 দরকার
avmohan

7

আপনি এর মতো পদ্ধতি রেফারেন্স ব্যবহার করতে পারেন:

user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);

পদ্ধতি ifPresent()পেতে Consumerএকটি paremeter যেমন বস্তু এবং (থেকে JavaDoc ): "যদি একটি মান, উপস্থিত মান নির্দিষ্ট ভোক্তা ডাকা।" মান এটি আপনার পরিবর্তনশীল user

অথবা যদি এই পদ্ধতি doSomethingWithUserরয়েছে Userশ্রেণী এবং তা না হয় static, আপনি এটির মতো পদ্ধতি রেফারেন্স ব্যবহার করতে পারেন:

user.ifPresent(this::doSomethingWithUser);

4
তবে doSomethingWithUser একটি স্থিতিশীল পদ্ধতি নয় বা এটি শ্রেণিবদ্ধ।
রায়মান

@ রাইমন ওকে, স্থিতিশীল না হলে আপনি এটি করতে পারেন:user.ifPresent(new ClassNameWhereMethodIs()::doSomethingWithUser);
আলেকসান্দ্র পোডকুটিন

7
@ আলেকসান্দ্রপডকুটিন আপনি কেবল একটি পদ্ধতি চালানোর জন্য ক্লাসের একটি নতুন উদাহরণ তৈরি করবেন না, ওপি থেকে মনে হচ্ছে পদ্ধতিটি একই শ্রেণিতে রয়েছে যেহেতু এটি আহ্বান করা হচ্ছে, সুতরাং তার ব্যবহার করা উচিতuser.ifPresent(this::doSomethingWithUser);
মারভ

@ মারভ আমি একই ধরণের ওপেন দেখতে পাচ্ছি না যে এটি একই শ্রেণিতে রয়েছে। তবে আপনার যদি এইরকম অনুভূতি হয় তবে আমি সম্মতি জানাই যে তাকে ব্যবহার করতে হবে user.ifPresent(this::doSomethingWithUser);। আমি আমার উত্তরে এটি যুক্ত করব।
আলেকসান্ডার পোডকুটিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.