আমার যদি একটি থাকে তবে আমি List<List<Object>>
কীভাবে List<Object>
জাভা 8 এর বৈশিষ্ট্যগুলি ব্যবহার করে একই পুনরাবৃত্তির ক্রমে সমস্ত অবজেক্টগুলিকে এমন একটিতে পরিণত করব?
আমার যদি একটি থাকে তবে আমি List<List<Object>>
কীভাবে List<Object>
জাভা 8 এর বৈশিষ্ট্যগুলি ব্যবহার করে একই পুনরাবৃত্তির ক্রমে সমস্ত অবজেক্টগুলিকে এমন একটিতে পরিণত করব?
উত্তর:
আপনি flatMap
অভ্যন্তরীণ তালিকাগুলি (স্ট্রিমগুলিতে রূপান্তরিত করার পরে) একটি একক স্ট্রিমে সমতল করতে ব্যবহার করতে পারেন এবং তারপরে ফলাফলটি একটি তালিকাতে সংগ্রহ করুন:
List<List<Object>> list = ...
List<Object> flat =
list.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
Class::method
প্রথমে কিছুটা অদ্ভুত লাগছে তবে এতে সুবিধা হয় যে এটি ঘোষণা করে যে আপনি কোন ধরণের বস্তুটি ম্যাপ করছেন। এটি এমন একটি বিষয় যা আপনি অন্যথায় স্রোতে হারাবেন।
flatMap
উপর পদ্ধতি Stream
করতে পারেন অবশ্যই তোমার জন্য ঐ তালিকা চেপ্টা, কিন্তু এটা তৈরি করতে হবে Stream
তারপর একটি উপাদানের জন্য বস্তু, Stream
ফলাফলের জন্য।
আপনার এই সমস্ত Stream
বস্তুর দরকার নেই । কাজটি সম্পাদন করার জন্য এখানে সরল, সংক্ষিপ্ত কোডটি দেওয়া হল।
// listOfLists is a List<List<Object>>.
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);
কারণ List
হ'ল Iterable
, এই কোডটি পদ্ধতিটিকে (জাভা 8 বৈশিষ্ট্য) কল করেforEach
যা উত্তরাধিকার সূত্রে প্রাপ্ত Iterable
।
Iterable
সমস্ত উপাদান প্রক্রিয়া না করা বা ক্রিয়াটি একটি ব্যতিক্রম ছুঁড়ে না দেওয়া পর্যন্ত প্রতিটি উপাদানের প্রদত্ত ক্রিয়া সম্পাদন করে । ক্রমগুলি পুনরাবৃত্তির ক্রমে সঞ্চালিত হয়, যদি সেই আদেশটি নির্দিষ্ট করা থাকে।
আর List
এর Iterator
অনুক্রমিক অনুক্রমে আয় আইটেম।
এর জন্য Consumer
, এই কোডটি একটি পদ্ধতি রেফারেন্সে (জাভা 8 বৈশিষ্ট্য) পূর্ব-জাভা 8 পদ্ধতিতে List.addAll
অনুক্রমিকভাবে অভ্যন্তরীণ তালিকার উপাদানগুলি যুক্ত করতে পাস করে ।
নির্দিষ্ট সংগ্রহের পুনরাবৃত্তকারী (alচ্ছিক ক্রিয়াকলাপ) দ্বারা এগুলি প্রদান করা হয় সেই ক্রমে এই তালিকাটির শেষে নির্দিষ্ট সংকলনের সমস্ত উপাদান যুক্ত করে।
আপনি Elpipse সংগ্রহflatCollect()
থেকে প্যাটার্নটি ব্যবহার করতে পারেন ।
MutableList<List<Object>> list = Lists.mutable.empty();
MutableList<Object> flat = list.flatCollect(each -> each);
আপনি যদি তালিকাটি পরিবর্তন করতে না পারেন তবে List
:
List<List<Object>> list = new ArrayList<>();
List<Object> flat = ListAdapter.adapt(list).flatCollect(each -> each);
দ্রষ্টব্য: আমি গ্রহন গ্রাহক সংগ্রহের একজন সহযোগী।
ঠিক যেমন @ সরভানার উল্লেখ করেছেন:
ফ্ল্যাটম্যাপ আরও ভাল তবে এটি অর্জনের অন্যান্য উপায়ও রয়েছে
listStream.reduce(new ArrayList<>(), (l1, l2) -> {
l1.addAll(l2);
return l1;
});
সংক্ষেপে বলতে গেলে, নিম্নলিখিতটি অর্জনের বিভিন্ন উপায় রয়েছে:
private <T> List<T> mergeOne(Stream<List<T>> listStream) {
return listStream.flatMap(List::stream).collect(toList());
}
private <T> List<T> mergeTwo(Stream<List<T>> listStream) {
List<T> result = new ArrayList<>();
listStream.forEach(result::addAll);
return result;
}
private <T> List<T> mergeThree(Stream<List<T>> listStream) {
return listStream.reduce(new ArrayList<>(), (l1, l2) -> {
l1.addAll(l2);
return l1;
});
}
private <T> List<T> mergeFour(Stream<List<T>> listStream) {
return listStream.reduce((l1, l2) -> {
List<T> l = new ArrayList<>(l1);
l.addAll(l2);
return l;
}).orElse(new ArrayList<>());
}
private <T> List<T> mergeFive(Stream<List<T>> listStream) {
return listStream.collect(ArrayList::new, List::addAll, List::addAll);
}
আমি শুধু মত আরও একটি দৃশ্যকল্প ব্যাখ্যা করতে চান List<Documents>
, এই তালিকা মত অন্যান্য নথি আরো কয়েকটি তালিকা রয়েছে List<Excel>
, List<Word>
, List<PowerPoint>
। সুতরাং কাঠামো হয়
class A {
List<Documents> documentList;
}
class Documents {
List<Excel> excels;
List<Word> words;
List<PowerPoint> ppt;
}
এখন আপনি যদি কেবলমাত্র ডকুমেন্টগুলি থেকে এক্সেল পুনরাবৃত্তি করতে চান তবে নীচের মতো কিছু করুন ..
সুতরাং কোড হবে
List<Documents> documentList = new A().getDocumentList();
//check documentList as not null
Optional<Excel> excelOptional = documentList.stream()
.map(doc -> doc.getExcel())
.flatMap(List::stream).findFirst();
if(excelOptional.isPresent()){
Excel exl = optionalExcel.get();
// now get the value what you want.
}
আমি আশা করি কোডিংয়ের সময় এটি কারও সমস্যা সমাধান করতে পারে ...
আমরা এর জন্য ফ্ল্যাটম্যাপ ব্যবহার করতে পারি, দয়া করে নীচের কোডটি উল্লেখ করুন:
List<Integer> i1= Arrays.asList(1, 2, 3, 4);
List<Integer> i2= Arrays.asList(5, 6, 7, 8);
List<List<Integer>> ii= Arrays.asList(i1, i2);
System.out.println("List<List<Integer>>"+ii);
List<Integer> flat=ii.stream().flatMap(l-> l.stream()).collect(Collectors.toList());
System.out.println("Flattened to List<Integer>"+flat);
ইরানের উত্তরের একটি প্রসার যা শীর্ষস্থানীয় উত্তর ছিল, যদি আপনার তালিকাগুলির একগুচ্ছ স্তর থাকে তবে আপনি সেগুলি ফ্ল্যাটম্যাপিং রাখতে পারেন।
এটি ফিল্টারিংয়ের একটি সহজ পদ্ধতিতেও আসে যখন আপনি প্রয়োজনে স্তরগুলি নীচে যেতে পারেন।
উদাহরণস্বরূপ:
List<List<List<List<List<List<Object>>>>>> multiLayeredList = ...
List<Object> objectList = multiLayeredList
.stream()
.flatmap(someList1 -> someList1
.stream()
.filter(...Optional...))
.flatmap(someList2 -> someList2
.stream()
.filter(...Optional...))
.flatmap(someList3 -> someList3
.stream()
.filter(...Optional...))
...
.collect(Collectors.toList())
এটি এসকিউএল-তে অনুরূপ নির্বাচনী বয়ানগুলির মধ্যে নির্বাচনী বক্তব্য রাখার মতো হবে।
পদ্ধতি রূপান্তর করতে List<List>
করতে List
:
listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());
এই উদাহরণটি দেখুন:
public class Example {
public static void main(String[] args) {
List<List<String>> listOfLists = Collections.singletonList(Arrays.asList("a", "b", "v"));
List<String> list = listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());
System.out.println("listOfLists => " + listOfLists);
System.out.println("list => " + list);
}
}
এটি প্রিন্ট করে:
listOfLists => [[a, b, c]]
list => [a, b, c]
::
:) এর চেহারাটি আমি পছন্দ করি না