আমি কীভাবে জাভা 8-এর তালিকাগুলির তালিকাকে একটি তালিকায় পরিণত করতে পারি?


532

আমার যদি একটি থাকে তবে আমি List<List<Object>>কীভাবে List<Object>জাভা 8 এর বৈশিষ্ট্যগুলি ব্যবহার করে একই পুনরাবৃত্তির ক্রমে সমস্ত অবজেক্টগুলিকে এমন একটিতে পরিণত করব?

উত্তর:


950

আপনি flatMapঅভ্যন্তরীণ তালিকাগুলি (স্ট্রিমগুলিতে রূপান্তরিত করার পরে) একটি একক স্ট্রিমে সমতল করতে ব্যবহার করতে পারেন এবং তারপরে ফলাফলটি একটি তালিকাতে সংগ্রহ করুন:

List<List<Object>> list = ...
List<Object> flat = 
    list.stream()
        .flatMap(List::stream)
        .collect(Collectors.toList());

11
@ আরশজিই সত্য, তবে কিছু কারণে আমি ল্যাম্বডা ভাবটি পছন্দ করি। সম্ভবত :::) এর চেহারাটি আমি পছন্দ করি না
এরান

25
Class::methodপ্রথমে কিছুটা অদ্ভুত লাগছে তবে এতে সুবিধা হয় যে এটি ঘোষণা করে যে আপনি কোন ধরণের বস্তুটি ম্যাপ করছেন। এটি এমন একটি বিষয় যা আপনি অন্যথায় স্রোতে হারাবেন।
আরনেহুগো 15'16

2
তবুও আপনি একটি তালিকার একটি ধারক পেতে চাইতে পারেন এবং সেক্ষেত্রে আপনাকে ল্যাম্বদা (l-> l.myList.stream ()) ব্যবহার করতে হবে।
মায়োচ

2
আপনার যদি সুস্পষ্ট কাস্টিংয়ের প্রয়োজন হয় (উদাহরণস্বরূপ তালিকায় আদিমগুলির অ্যারে) তবে ল্যাম্বডাসও প্রয়োজনীয় হতে পারে।
মাইকেল ফুলটন

52

flatmap ভাল তবে এটি অর্জনের অন্যান্য উপায়ও রয়েছে

List<List<Object>> listOfList = ... // fill

List<Object> collect = 
      listOfList.stream()
                .collect(ArrayList::new, List::addAll, List::addAll);

37

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চ্ছিক ক্রিয়াকলাপ) দ্বারা এগুলি প্রদান করা হয় সেই ক্রমে এই তালিকাটির শেষে নির্দিষ্ট সংকলনের সমস্ত উপাদান যুক্ত করে।


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

12

আপনি 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);

দ্রষ্টব্য: আমি গ্রহন গ্রাহক সংগ্রহের একজন সহযোগী।


21
যখন জাভা 8 দ্বারা কার্যকারিতা সরবরাহ করা হয় তখন তৃতীয় পক্ষের নির্ভরতা কেন ব্যবহার করবেন?
3030

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

11

ঠিক যেমন @ সরভানার উল্লেখ করেছেন:

ফ্ল্যাটম্যাপ আরও ভাল তবে এটি অর্জনের অন্যান্য উপায়ও রয়েছে

 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);
}

11

আমি শুধু মত আরও একটি দৃশ্যকল্প ব্যাখ্যা করতে চান 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.
 }

আমি আশা করি কোডিংয়ের সময় এটি কারও সমস্যা সমাধান করতে পারে ...


1

আমরা এর জন্য ফ্ল্যাটম্যাপ ব্যবহার করতে পারি, দয়া করে নীচের কোডটি উল্লেখ করুন:

 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);

1

ইরানের উত্তরের একটি প্রসার যা শীর্ষস্থানীয় উত্তর ছিল, যদি আপনার তালিকাগুলির একগুচ্ছ স্তর থাকে তবে আপনি সেগুলি ফ্ল্যাটম্যাপিং রাখতে পারেন।

এটি ফিল্টারিংয়ের একটি সহজ পদ্ধতিতেও আসে যখন আপনি প্রয়োজনে স্তরগুলি নীচে যেতে পারেন।

উদাহরণস্বরূপ:

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())

এটি এসকিউএল-তে অনুরূপ নির্বাচনী বয়ানগুলির মধ্যে নির্বাচনী বক্তব্য রাখার মতো হবে।


1

পদ্ধতি রূপান্তর করতে 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]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.