জাভা 8 লাম্বডাস বনাম অজ্ঞাতনামা ক্লাস


111

যেহেতু জাভা 8 সম্প্রতি প্রকাশিত হয়েছে এবং এর ব্র্যান্ডের নতুন ল্যাম্বডা এক্সপ্রেশনগুলি দেখতে দুর্দান্ত লাগছে, তাই আমি ভাবছিলাম যে এটি অনামিকার শ্রেণীর মৃত্যুর অর্থ যা আমরা এতদিন ব্যবহার করতাম।

আমি এ সম্পর্কে কিছুটা গবেষণা করে চলেছি এবং ল্যাম্বদা এক্সপ্রেশনগুলি কীভাবে এই ক্লাসগুলিকে পদ্ধতিগতভাবে প্রতিস্থাপন করবে সে সম্পর্কে কয়েকটি দুর্দান্ত উদাহরণ পেয়েছি, যেমন সংগ্রহের বাছাই পদ্ধতি, যা তুলনা করার জন্য তুলনাকারীর একটি অনামী উদাহরণ পেয়েছিল:

Collections.sort(personList, new Comparator<Person>(){
  public int compare(Person p1, Person p2){
    return p1.firstName.compareTo(p2.firstName);
  }
});

এখন ল্যাম্বডাস ব্যবহার করে করা যেতে পারে:

Collections.sort(personList, (Person p1, Person p2) -> p1.firstName.compareTo(p2.firstName));

এবং অবাকভাবে সংক্ষিপ্ত দেখাচ্ছে। সুতরাং আমার প্রশ্নটি হচ্ছে, ল্যাম্বডাসের পরিবর্তে জাভা 8-এ এই ক্লাসগুলি ব্যবহার করার কোনও কারণ আছে কি?

সম্পাদনা

একই প্রশ্ন কিন্তু বিপরীত দিকে, বেনাম শ্রেণীর পরিবর্তে লাম্বডাস ব্যবহারের কী কী সুবিধা রয়েছে, যেহেতু লাম্বডাস কেবলমাত্র একক পদ্ধতিতে ইন্টারফেসের সাথে ব্যবহার করা যেতে পারে, এই নতুন বৈশিষ্ট্যটি কেবলমাত্র কয়েকটি ক্ষেত্রে ব্যবহৃত একটি শর্টকাট বা এটি সত্যিই কার্যকর?


5
অবশ্যই, সেই সমস্ত বেনাম শ্রেণীর জন্য যা পার্শ্ব প্রতিক্রিয়া সহ পদ্ধতিগুলি সরবরাহ করে।
tobias_k

11
কেবল আপনার তথ্যের জন্য আপনি তুলনাকারীটিও এটি তৈরি করতে পারেন: Comparator.comparing(Person::getFirstName)যদি getFirstName()কোনও পদ্ধতি ফেরত আসে firstName
স্কিভি

1
বা একাধিক পদ্ধতির সাথে
বেনাম

1
আমি খুব প্রসারিত হিসাবে কাছাকাছি ভোট দিতে প্রলুব্ধ, বিশেষত EDIT পরে অতিরিক্ত প্রশ্নের কারণে ।
মার্ক রোটভেল

উত্তর:


108

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

আমি অনুমান করতে পারি যে এআইসির বেশিরভাগ ব্যবহার ছিল একক ফাংশনের রাষ্ট্রহীন বাস্তবায়ন এবং ল্যাম্বডা এক্সপ্রেশন দিয়ে প্রতিস্থাপন করা যেতে পারে তবে এআইসির অন্যান্য ব্যবহার রয়েছে যার জন্য ল্যাম্বডাস ব্যবহার করা যায় না cannot AICs এখানে থাকার জন্য।

হালনাগাদ

এআইসি এবং ল্যাম্বডা এক্সপ্রেশনগুলির মধ্যে আর একটি পার্থক্য হ'ল এআইসি একটি নতুন সুযোগ প্রবর্তন করে। এটি হ'ল, নামগুলি এআইসির সুপারক্লাস এবং ইন্টারফেসগুলি থেকে সমাধান করা হয় এবং লেক্সিক্যালি বদ্ধ পরিবেশে ঘটে এমন নামগুলি ছায়া দিতে পারে। ল্যাম্বডাসের জন্য সমস্ত নাম বর্ণহীনভাবে সমাধান করা হয়।


1
লাম্বদাসের রাজ্য থাকতে পারে। এই শ্রদ্ধায়, আমি ল্যাম্বডাস এবং এআইসির মধ্যে কোনও পার্থক্য দেখছি না।
নসিড

1
@ নোসিড এআইসি, যে কোনও শ্রেণির উদাহরণের মতো, ক্ষেত্রগুলিতে রাষ্ট্রকে ধরে রাখতে পারে এবং এই রাষ্ট্রটি শ্রেণীর যে কোনও পদ্ধতিতে (এবং সম্ভাব্যভাবে পরিবর্তনযোগ্য) অ্যাক্সেসযোগ্য। এই রাজ্যটি অবধি অবধি অবধি অবধি অবধি অবধি অবধি উপস্থিত থাকে না, এটির অনির্দিষ্ট পরিমাণ থাকে, সুতরাং এটি পদ্ধতি কলগুলিতে অবিচল থাকতে পারে। ল্যাম্বডাসের মুখোমুখি হওয়ার সময় কেবলমাত্র অনির্দিষ্টকালের লাম্বডাস রাজ্যটি দখল করা হয়েছিল; এই রাষ্ট্র অপরিবর্তনীয়। একটি ল্যাম্বডারের মধ্যে স্থানীয় ভেরিয়েবলগুলি পরিবর্তনীয়, তবে লাম্বদা আহরণের প্রক্রিয়া চলাকালীন তখন এগুলি বিদ্যমান।
স্টুয়ার্ট 0

1
@ নোশিদ আহ, একক-উপাদান অ্যারে হ্যাক। একাধিক থ্রেড থেকে কেবল আপনার কাউন্টারটি ব্যবহার করার চেষ্টা করবেন না। আপনি যদি গাদা কিছু বরাদ্দ করতে এবং একটি ল্যাম্বডায় এটি ক্যাপচার করতে যাচ্ছেন তবে আপনি সম্ভবত একটি এআইসি ব্যবহার করতে পারেন এবং এমন ক্ষেত্র যুক্ত করতে পারেন যা আপনি সরাসরি পরিবর্তন করতে পারেন। ল্যাম্বডা এভাবে ব্যবহার করা কাজ করতে পারে তবে আপনি যখন সত্যিকারের বস্তুটি ব্যবহার করতে পারেন তখন কেন বিরক্ত হন?
স্টুয়ার্ট

2
এআইসি এই জাতীয় একটি ফাইল তৈরি করবে, A$1.classতবে ল্যাম্বদা তা করবে না। আমি কি পার্থক্যটিতে এটি যুক্ত করতে পারি?
আসিফ মোশতাক

2
@ অজানা এটি মূলত একটি বাস্তবায়নের উদ্বেগ; এটি এআইসিস বনাম ল্যাম্বডাসের সাথে একটি প্রোগ্রাম কীভাবে প্রভাবিত করে না, যা এই প্রশ্নটি বেশিরভাগ ক্ষেত্রে। নোট করুন যে একটি ল্যাম্বডা এক্সপ্রেশন একটি নামের মতো একটি বর্গ তৈরি করে LambdaClass$$Lambda$1/1078694789। যাইহোক, এই শ্রেণিটি ল্যাম্বদা মেটাফ্যাক্টরি দ্বারা ফ্লাইটে তৈরি করা হয়েছে, দ্বারা নয় javac, সুতরাং কোনও সম্পর্কিত .classফাইল নেই। আবার, তবে এটি বাস্তবায়নের উদ্বেগ।
স্টুয়ার্ট

60

ল্যাম্বডাস যদিও দুর্দান্ত বৈশিষ্ট্যযুক্ত তবে কেবল এসএএম টাইপের সাথে কাজ করবে will এটি হল, শুধুমাত্র একটি বিমূর্ত পদ্ধতি সহ ইন্টারফেসগুলি s আপনার ইন্টারফেসে 1 টিরও বেশি বিমূর্ত পদ্ধতি থাকা মাত্রই এটি ব্যর্থ হবে। সেখানেই বেনাম শ্রেণি কার্যকর হবে।

সুতরাং, না, আমরা কেবল বেনাম শ্রেণীদের উপেক্ষা করতে পারি না। এবং শুধুমাত্র FYI, আপনার sort()পদ্ধতি আরো সরলীকৃত করা যেতে পারে, জন্য টাইপ ঘোষণা কুঁদন দ্বারা p1এবং p2:

Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName));

আপনি এখানে পদ্ধতি রেফারেন্সও ব্যবহার করতে পারেন। হয় আপনি ক্লাসে একটি compareByFirstName()পদ্ধতি যুক্ত করুন Personএবং ব্যবহার করুন:

Collections.sort(personList, Person::compareByFirstName);

বা, এর জন্য একটি গিটার যুক্ত করুন firstName, সরাসরি পদ্ধতি Comparatorথেকে পান Comparator.comparing():

Collections.sort(personList, Comparator.comparing(Person::getFirstName));

4
আমি জানতাম, তবে আমি পঠনযোগ্যতার দিক থেকে দীর্ঘটি পছন্দ করি কারণ অন্যথায় এই পরিবর্তনগুলি কোথা থেকে এসেছে তা খুঁজে বের করা বিভ্রান্তিকর হতে পারে।
আমিন আবু-তালেব

@ আমিনআবু-তালেব কেন বিভ্রান্তিকর হবে। এটি একটি বৈধ লাম্বদা সিনট্যাক্স। প্রকারগুলি যাইহোক অনুমান করা হয়। যাইহোক, এটি ব্যক্তিগত পছন্দ আপনি প্রকারভেদ দিতে পারেন। কোন কারণ নাই.
রোহিত জৈন

1
বেনামী শ্রেণীর সরাসরি নতুন সটীক করা যেতে পারে: আছে lambdas এবং বেনামী শ্রেণীর মধ্যে আরেকটি সূক্ষ্ম পার্থক্য আছে জাভা 8 প্রকার টীকা , যেমন যেমন new @MyTypeAnnotation SomeInterface(){};। ল্যাম্বডা এক্সপ্রেশনগুলির জন্য এটি সম্ভব নয়। বিশদগুলির জন্য, আমার প্রশ্নটি এখানে দেখুন: ল্যাম্বডা এক্সপ্রেশনটির ক্রিয়ামূলক ইন্টারফেসটিকে টীকা দেওয়া
বাল্ডার

36

বেনাম শ্রেণীর সাথে লাম্বদা পারফরম্যান্স

অ্যাপ্লিকেশন চালু হওয়ার সাথে সাথে প্রতিটি শ্রেণীর ফাইল অবশ্যই লোড এবং যাচাই করা উচিত।

বেনামী ক্লাসগুলি প্রদত্ত শ্রেণি বা ইন্টারফেসের জন্য একটি নতুন উপ-টাইপ হিসাবে সংকলক দ্বারা প্রক্রিয়াজাত করা হয়, সুতরাং প্রত্যেকটির জন্য একটি নতুন শ্রেণি ফাইল তৈরি করা হবে।

ল্যাম্বডাস বাইটকোড জেনারেশনে পৃথক, তারা আরও দক্ষ, জেডিকে with এর সাথে আসা ইনভোকডিনামিক নির্দেশাবলী।

লাম্বডাসের জন্য এই নির্দেশটি লম্বা এক্সপ্রেশনটি বিলম্ব করার জন্য বাইটোকড আনটাইল রানটাইমটিতে বিলম্ব করতে ব্যবহৃত হয়। (নির্দেশটি প্রথমবারের জন্য ডাকা হবে)

ফলস্বরূপ লাম্বদা এক্সপ্রেশন একটি স্থির পদ্ধতিতে পরিণত হবে (রানটাইম সময়ে তৈরি)। (স্টেটল এবং স্টেটফুল মামলাগুলির সাথে সামান্য পার্থক্য রয়েছে, তারা উত্পন্ন পদ্ধতি আর্গুমেন্টের মাধ্যমে সমাধান করা হয়)


প্রতিটি ল্যাম্বডায় নতুন ক্লাসের প্রয়োজন হয়, তবে এটি রানটাইমের সময় উত্পন্ন হয়, সুতরাং এই অর্থে ল্যাম্বডাস বেনাম শ্রেণীর চেয়ে বেশি দক্ষ নয়। লাম্বডাস তৈরি করা হয়েছে invokedynamicযার মাধ্যমে বেনাম invokespecialশ্রেণীর নতুন দৃষ্টান্ত তৈরি করার জন্য সাধারণত ধীর হয় slow সুতরাং, এই অর্থে ল্যাম্বডাস খুব ধীর হয় (তবে, জেভিএম invokedynamicবেশিরভাগ সময় কলগুলি অনুকূল করতে পারে )।
ZhekaKozlov 4

3
@ আন্দ্রেইটোমাশপলস্কি ১. অনুগ্রহ করে বিনয়ী হন। 2. একটি সংকলক ইঞ্জিনিয়ারের এই মন্তব্যটি পড়ুন: habrahabr.ru/post/313350/comments/#comment_9885460
ZhekaKozlov

@ Kaেকা কোজলভ, জেআরই সোর্স কোড পড়তে এবং জাভাপ / ডিবাগার ব্যবহার করার জন্য আপনাকে সংকলক ইঞ্জিনিয়ার হওয়ার দরকার নেই। আপনি যেটি মিস করছেন তা হ'ল ল্যাম্বডা পদ্ধতির জন্য একটি মোড়কের ক্লাসের প্রজন্ম সম্পূর্ণ মেমরির মধ্যে সম্পন্ন হয় এবং কোনও ব্যয়ের পরে ব্যয় হয় না, যখন কোনও এআইসি তাত্ক্ষণিকভাবে সংশ্লিষ্ট শ্রেণীর সংস্থান সমাধান করা এবং লোড করা জড়িত (যার অর্থ I / O সিস্টেম কল)। সুতরাং, invokedynamicসংঘবদ্ধ বেনাম শ্রেণীর তুলনায় অ্যাড-হক ক্লাস প্রজন্ম দ্রুত জ্বলছে।
আন্দ্রেই তোমাশপলস্কি

@ আন্দ্রেইটোমাশপলস্কি আই / ও অগত্যা ধীর নয়
Zেকাকোজলভ

14

নিম্নলিখিত পার্থক্য রয়েছে:

1) সিনট্যাক্স

অজ্ঞাতনামা ইনার ক্লাস (এআইসি) এর তুলনায় লাম্বদা এক্সপ্রেশনগুলি ঝরঝরে দেখাচ্ছে

public static void main(String[] args) {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            System.out.println("in run");
        }
    };

    Thread t = new Thread(r);
    t.start(); 
}

//syntax of lambda expression 
public static void main(String[] args) {
    Runnable r = ()->{System.out.println("in run");};
    Thread t = new Thread(r);
    t.start();
}

2) ব্যাপ্তি

একটি বেনামি অভ্যন্তরীণ শ্রেণি একটি শ্রেণি, যার অর্থ এটির অভ্যন্তর শ্রেণীর অভ্যন্তরে পরিবর্তিত সংখ্যার জন্য সুযোগ রয়েছে।

যদিও ল্যাম্বডা এক্সপ্রেশনটি তার নিজস্ব সুযোগ নয়, তবে ঘেরের সুযোগের একটি অংশ।

অজ্ঞাতনামা অভ্যন্তরীণ বর্গ এবং ল্যাম্বদা এক্সপ্রেশন ব্যবহার করার সময় সুপার এবং এই কীওয়ার্ডের জন্য অনুরূপ নিয়ম প্রযোজ্য । বেনামি অভ্যন্তর শ্রেণীর ক্ষেত্রে এই কীওয়ার্ডটি স্থানীয় সুযোগকে বোঝায় এবং সুপার কীওয়ার্ডটি বেনাম শ্রেণীর সুপার ক্লাসকে বোঝায়। ল্যাম্বডা এক্সপ্রেশনের ক্ষেত্রে এই কীওয়ার্ডটি এনক্লোজিং টাইপের অবজেক্টকে বোঝায় এবং সুপারটি এনকোলেসিং ক্লাসের সুপার ক্লাসকে বোঝায়।

//AIC
    public static void main(String[] args) {
        final int cnt = 0; 
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int cnt = 5;    
                System.out.println("in run" + cnt);
            }
        };

        Thread t = new Thread(r);
        t.start();
    }

//Lambda
    public static void main(String[] args) {
        final int cnt = 0; 
        Runnable r = ()->{
            int cnt = 5; //compilation error
            System.out.println("in run"+cnt);};
        Thread t = new Thread(r);
        t.start();
    }

3) পারফরম্যান্স

রানটাইম বেনামে অভ্যন্তরীণ ক্লাসগুলির জন্য বর্গ লোডিং, মেমরি বরাদ্দকরণ এবং অবজেক্টের সূচনা এবং অ স্থিত পদ্ধতির প্রার্থনা প্রয়োজন যখন ল্যাম্বডা এক্সপ্রেশনটি খাঁটি সংকলন সময় ক্রিয়াকলাপ এবং রানটাইমের সময় অতিরিক্ত ব্যয় ব্যয় করবেন না। সুতরাং বেনামে অভ্যন্তর শ্রেণীর তুলনায় ল্যাম্বডা এক্সপ্রেশনটির পারফরম্যান্স আরও ভাল *

** আমি বুঝতে পারি যে এই বিষয়টি সম্পূর্ণ সত্য নয়। বিস্তারিত জানার জন্য নীচের প্রশ্ন পড়ুন। লাম্বদা বনাম বেনামে অভ্যন্তরীণ শ্রেণীর পারফরম্যান্স: ক্লাসলোডারের বোঝা কমান?


3

জাভা 8-এ লাম্বডা কার্যকরী প্রোগ্রামিংয়ের জন্য চালু হয়েছিল। যেখানে আপনি বয়লারপ্লেট কোড এড়াতে পারবেন। ল্যাম্বদার এই আকর্ষণীয় নিবন্ধটি জুড়ে এসেছি।

http://radar.oreilly.com/2014/04/whats-new-in-java-8-lambdas.html

সাধারণ লজিকগুলির জন্য ল্যাম্বদা ফাংশন ব্যবহার করার পরামর্শ দেওয়া হচ্ছে। ল্যাম্বডাস ব্যবহার করে জটিল যুক্তি প্রয়োগ করা হলে ইস্যু হওয়ার ক্ষেত্রে কোডটি ডিবাগ করার ক্ষেত্রে ওভারহেড হবে।


0

বেনামে ক্লাস থাকার জন্য আছে কারণ ল্যাম্বদা একক বিমূর্ত পদ্ধতি সহ ফাংশনগুলির জন্য ভাল তবে অন্যান্য সমস্ত ক্ষেত্রে বেনামে অভ্যন্তর শ্রেণিগুলি আপনার ত্রাণকর্তা।


-1
  • লাম্বদা সিনট্যাক্সের জন্য জাভা অনুমান করতে পারে সেই স্পষ্ট কোডটি লেখার প্রয়োজন নেই।
  • ব্যবহার করে invoke dynamic, ল্যাম্বদা সংকলনের সময় বেনামে আবার শ্রেণিতে রূপান্তরিত হয় না (জাভাকে বস্তু তৈরির মধ্য দিয়ে যেতে হবে না, কেবল পদ্ধতিটির স্বাক্ষরের যত্ন নেওয়া, অবজেক্ট তৈরি না করেই পদ্ধতিতে আবদ্ধ থাকতে পারে)
  • ল্যাম্বদা এটি করার আগে আমাদের যা করতে হবে তার পরিবর্তে আমরা কী করতে চাই তার উপরে আরও জোর দিয়েছি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.