লাম্বদা এক্সপ্রেশন এবং জেনেরিক পদ্ধতি


111

ধরুন আমি একটি জেনেরিক ইন্টারফেস করেছি:

interface MyComparable<T extends Comparable<T>>  {
    public int compare(T obj1, T obj2);
}

এবং একটি পদ্ধতি sort:

public static <T extends Comparable<T>> 
       void sort(List<T> list, MyComparable<T> comp) {
    // sort the list
}

আমি এই পদ্ধতিটি চালিত করতে এবং যুক্তি হিসাবে ল্যাম্বডা এক্সপ্রেশনটি পাস করতে পারি:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

এটা ঠিক কাজ করবে।

তবে এখন যদি আমি ইন্টারফেসটি অ-জেনেরিক এবং পদ্ধতিটি জেনেরিক করি:

interface MyComparable {
    public <T extends Comparable<T>> int compare(T obj1, T obj2);
}

public static <T extends Comparable<T>> 
       void sort(List<T> list, MyComparable comp) {
}

এবং তারপরে এটি শুরু করুন:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

এটি সংকলন করে না এটি ল্যাম্বডা এক্সপ্রেশনটিতে ত্রুটি দেখায়:

"লক্ষ্য পদ্ধতি জেনেরিক"

ঠিক আছে, যখন আমি এটি ব্যবহার করে সংকলন করি তখন javacএটি নিম্নলিখিত ত্রুটিটি দেখায়:

SO.java:20: error: incompatible types: cannot infer type-variable(s) T#1
        sort(list, (a, b) -> a.compareTo(b));
            ^
    (argument mismatch; invalid functional descriptor for lambda expression
      method <T#2>(T#2,T#2)int in interface MyComparable is generic)
  where T#1,T#2 are type-variables:
    T#1 extends Comparable<T#1> declared in method <T#1>sort(List<T#1>,MyComparable)
    T#2 extends Comparable<T#2> declared in method <T#2>compare(T#2,T#2)
1 error

এই ত্রুটি বার্তা থেকে, দেখে মনে হয় যে সংকলক প্রকারের আর্গুমেন্টগুলি নির্ধারণ করতে সক্ষম নয়। এটাই কি? যদি হ্যাঁ, তবে কেন এমন হচ্ছে?

আমি বিভিন্ন উপায়ে চেষ্টা করেছি, ইন্টারনেটে অনুসন্ধান করেছি। তারপরে আমি এই জাভাকোডিজিক্স নিবন্ধটি পেয়েছি , যা একটি উপায় দেখায়, তাই আমি চেষ্টা করেছি:

sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));

যা আবার কাজ করে না, সেই নিবন্ধটি দাবি করে যে এটি কাজ করে to সম্ভব হতে পারে যে এটি কিছু প্রাথমিক বিল্ডে কাজ করত।

সুতরাং আমার প্রশ্ন: জেনেরিক পদ্ধতির জন্য ল্যাম্বডা এক্সপ্রেশন তৈরির কোনও উপায় আছে কি? আমি যদিও কোনও পদ্ধতি তৈরি করে একটি পদ্ধতি রেফারেন্স ব্যবহার করে এটি করতে পারি:

public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
    return obj1.compareTo(obj2);
}

কিছু ক্লাসে বলে SO, এবং এটি পাস:

sort(list, SO::compare);

উত্তর:


117

আপনি একটি ব্যবহার করতে পারবেন না ল্যামডা অভিব্যক্তি একটি জন্য কার্মিক ইন্টারফেস , যদি পদ্ধতি কার্মিক ইন্টারফেস রয়েছে টাইপ প্যারামিটারজেএলএস 8 এ বিভাগ §15.27.3 দেখুন :

একটি ল্যামডা অভিব্যক্তি লক্ষ্য টাইপ সঙ্গে সামঞ্জস্যপূর্ণ [..] টি যদি টি একটি কার্মিক ইন্টারফেস প্রকার (§9.8) এবং অভিব্যক্তি সর্বসম ফাংশন ধরনের সঙ্গে [..] টি [..] একটি ল্যামডা অভিব্যক্তি সর্বসম নিম্নলিখিত ফাংশনটি সঠিক হলে একটি ফাংশনের ধরণের সাথে:

  • ফাংশন টাইপের কোনও ধরণের পরামিতি নেই
  • [..]

47
তবে জেনেরিক পদ্ধতিতে পদ্ধতির উল্লেখগুলির ক্ষেত্রে এই সীমাবদ্ধতা প্রযোজ্য নয় । আপনি জেনেরিক ফাংশনাল ইন্টারফেসের সাথে জেনেরিক পদ্ধতির কোনও পদ্ধতি রেফারেন্স ব্যবহার করতে পারেন।
ব্রায়ান গয়েটজ

17
আমি নিশ্চিত যে এই বিধিনিষেধের একটি ভাল কারণ আছে। এটা কি?
স্যান্ড্রো

6
@ সান্দ্রো: ল্যাম্বডা এক্সপ্রেশনটির জন্য টাইপ পরামিতিগুলি ঘোষণার জন্য কেবল কোনও বাক্য গঠন নেই। এবং এই ধরনের একটি বাক্য গঠন খুব জটিল হবে। মনে রাখবেন যে পার্সারটিকে এখনও অন্যান্য আইনী জাভা কনস্ট্রাকশনগুলি বাদ দিয়ে টাইপ পরামিতিগুলির সাথে এই জাতীয় ল্যাম্বডা এক্সপ্রেশন অবশ্যই বলতে সক্ষম হবে। সুতরাং আপনি পদ্ধতি রেফারেন্স অবলম্বন করতে হবে। লক্ষ্য পদ্ধতিটি একটি প্রতিষ্ঠিত বাক্য গঠন ব্যবহার করে প্রকারের পরামিতিগুলি ঘোষণা করতে পারে
হলগার

2
@ হোলজার স্টিল, যেখানে টাইপ প্যারামিটারগুলি স্বয়ংক্রিয়ভাবে কমিয়ে নেওয়া যেতে পারে, আপনি যখন উদাহরণ সেট <?> ঘোষণা করেন এবং সংঘবদ্ধ ধরনেরগুলির সাথে টাইপ-চেক করেন তখন সংকলক একটি ক্যাপচার টাইপটিকে এটির মতোই কমিয়ে ফেলতে পারে। অবশ্যই, এটি তাদের শরীরে টাইপ-পরামিতি হিসাবে দেওয়া অসম্ভব করে তোলে তবে আপনার যদি প্রয়োজন হয় তবে পদ্ধতির রেফারেন্সগুলি অবলম্বন করা একটি ভাল বিকল্প
WorldSEender

17

পদ্ধতির রেফারেন্স ব্যবহার করে, আমি যুক্তিটি পাস করার জন্য অন্য উপায় খুঁজে পেয়েছি:

List<String> list = Arrays.asList("a", "b", "c");        
sort(list, Comparable::<String>compareTo);

3

জেনেরিক তুলকের সঠিক সংস্করণটি কেবল পয়েন্টারে সংকলন করুন (Comparator<String>)

সুতরাং উত্তর হবে

sort(list, (Comparator<String>)(a, b) -> a.compareTo(b));


2
incompatible types: java.util.Comparator<java.lang.String> cannot be converted to MyComparableএবং MyComparableজেনেরিক নয় (কোনও প্রকারের নয়) তাই (MyComparable<String>)
কোনওভাবেই

1
আপনি কীভাবে @ কার্লোস হিউবার্গার কোডটি টাইপ করছেন তা জানেন না, তবে এটি আমার পক্ষে খুব ভালভাবে কাজ করে, আমি এটিই খুঁজছিলাম।
ইভান পেরেলস এম।

@IvanPeralesM। 2 মাস পরে ... আমি আপনার কোড অনুলিপি করে আটকিয়েছি এবং আপনার সাজান লাইনের উপরের লাইনটি অনুলিপি করে আটকিয়েছি - ঠিক এখানেই: আদর্শ one.com/YNwBbF ! আপনি কি নিশ্চিতরূপে উপরের কোডটি টাইপ করেছেন? ব্যবহার করছেন Compartor?
ব্যবহারকারী 85421

না, আমি উত্তরটির পিছনে ধারণাটি ব্যবহার করি, এটি কী ধরণের এবং এটি কাজ করে তা সংকলন করতে ফাংশনাল কাস্ট করতে।
ইভান পেরেলস এম।

@IvanPeralesM। ঠিক আছে, তাহলে আমার "টাইপিং" নিয়ে আপনার সমস্যা কী? উত্তরটি যেমন পোস্ট করা হয় তেমন কার্যকর হয় না।
ব্যবহারকারী 85421

0

তুমি এরকম কিছু বোঝাতে চাও ?:

<T,S>(T t, S s)->...

এই লম্বা কি ধরণের? আপনি জাভাতে এটি প্রকাশ করতে পারেননি এবং তাই কোনও ফাংশন অ্যাপ্লিকেশনে এই অভিব্যক্তিটি রচনা করতে পারবেন না এবং এক্সপ্রেশনগুলি কমপোজযোগ্য হতে হবে।

এটি কাজ করার জন্য আপনার জাভাতে র্যাঙ্ক 2 প্রকারের জন্য সহায়তা প্রয়োজন ।

পদ্ধতিগুলি জেনেরিক হওয়ার মঞ্জুরি দেওয়া হয় তবে আপনি এগুলিকে এক্সপ্রেশন হিসাবে ব্যবহার করতে পারেন নি। এগুলি তবে, আপনি তাদের পাস করার আগে প্রয়োজনীয় সমস্ত জেনেরিক ধরণের বিশেষত্ব দিয়ে ল্যাম্বডা অভিব্যক্তিতে হ্রাস করা যেতে পারে:ClassName::<TypeName>methodName


1
"Of what type is this lambda? You couldn't express that in Java..."প্রকারটি ব্যবহার করে টাইপটি ঠিক যেমন অন্য কোনও ল্যাম্বডা হিসাবে ব্যবহার করা হবে। ল্যাম্বডার ধরণটি ল্যাম্বডায় নিজেই স্পষ্টভাবে প্রকাশিত হয় না।
ক্রু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.