জাভা 8 স্ট্রিম ফ্ল্যাটম্যাপ পদ্ধতির উদাহরণ


86

আমি আসন্ন চেক করা হয়েছে Java update, যথা: Java 8 or JDK 8। হ্যাঁ, আমি অধৈর্য, ​​সেখানে প্রচুর নতুন জিনিস রয়েছে, তবে, এমন কিছু আছে যা আমি বুঝতে পারি না, কিছু সাধারণ কোড:

final Stream<Integer>stream = Stream.of(1,2,3,4,5,6,7,8,9,10);
stream.flatMap();

javadocs হয়

public <R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

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

কেউ প্রশংসিত বাস্তব জীবনের উদাহরণ তৈরি করে যদি flatMapআপনি পূর্ববর্তী জাভা সংস্করণগুলিতে এটি কোড Java[6,7]করতে পারেন এবং আপনি কীভাবে একই রুটিনগুলি ব্যবহার করে কোড করতে পারেন তবে আমি প্রশংসা করব Java 8


4
ইন্টারনেটে ফ্ল্যাটম্যাপ ব্যবহারের প্রায় মিলিয়ন উদাহরণ রয়েছে (কমপক্ষে স্কালার জন্য এবং সেগুলি মূলত একই) :) আপনি কী অনুসন্ধান করার চেষ্টা করেছেন? এখানে প্রথম শুরু করেছেন: ব্রান্টন -স্পাল.কম.উক
পিটার


আমার অর্থ হ'ল ফ্ল্যাটম্যাপ একটি সাধারণ ধারণা যা এখন জাভা এবং স্কালায় বিদ্যমান।
পিটার সোভেনসন

ঠিক আছে আমি এটি সম্পর্কে আরও পড়তে হবে ধন্যবাদ মানুষ।
চিপার্তেটিজ

10
জাভাতে ফ্ল্যাটম্যাপ একই ধারণা তবে স্ট্রিমগুলির সাথে বেশ আলাদা দেখাচ্ছে। লোককে স্কালায় নির্দেশ করবেন না!
অরবফিশ

উত্তর:


158

আপনি ইতিমধ্যে সমতল এমন স্ট্রিমটিরflatMap কোনও অর্থ হয় না , যেমনটি আপনি আপনার প্রশ্নের মতো দেখিয়েছেন। Stream<Integer>

তবে, আপনার যদি Stream<List<Integer>>এটি থাকে তবে তা বোধগম্য হবে এবং আপনি এটি করতে পারেন:

Stream<List<Integer>> integerListStream = Stream.of(
    Arrays.asList(1, 2), 
    Arrays.asList(3, 4), 
    Arrays.asList(5)
);

Stream<Integer> integerStream = integerListStream .flatMap(Collection::stream);
integerStream.forEach(System.out::println);

যা মুদ্রণ করবে:

1
2
3
4
5

এই প্রাক জাভা 8 করতে আপনার কেবল একটি লুপগুলি দরকার:

List<List<Integer>> integerLists = Arrays.asList(
    Arrays.asList(1, 2), 
    Arrays.asList(3, 4), 
    Arrays.asList(5)
)

List<Integer> flattened = new ArrayList<>();

for (List<Integer> integerList : integerLists) {
    flattened.addAll(integerList);
}

for (Integer i : flattened) {
    System.out.println(i);
}

113

উদাহরণস্বরূপ তৈরি

কল্পনা করুন যে আপনি নিম্নলিখিত ক্রমটি তৈরি করতে চান: 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 ইত্যাদি (অন্য কথায়: 1x1, 2x2, 3x3 ইত্যাদি)

সঙ্গে flatMapএটা কেমন দেখাতে পারে:

IntStream sequence = IntStream.rangeClosed(1, 4)
                          .flatMap(i -> IntStream.iterate(i, identity()).limit(i));
sequence.forEach(System.out::println);

কোথায়:

  • IntStream.rangeClosed(1, 4)intসহ 1 থেকে 4 পর্যন্ত একটি স্ট্রিম তৈরি করে
  • IntStream.iterate(i, identity()).limit(i)আমি দৈর্ঘ্যের আই প্রবাহ তৈরি intকরি - সুতরাং i = 4এটি প্রয়োগ করা একটি স্ট্রিম তৈরি করে:4, 4, 4, 4
  • flatMap স্ট্রিমটিকে "সমতল" করে এবং এটিকে মূল স্ট্রিমের সাথে "যুক্ত করে"

জাভা <8 এর সাথে আপনার দুটি নেস্টেড লুপের দরকার হবে:

List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 4; i++) {
    for (int j = 0; j < i; j++) {
        list.add(i);
    }
}

বাস্তব বিশ্বের উদাহরণ

ধরা যাক আমার কাছে এমন একটি রয়েছে List<TimeSeries>যেখানে প্রতিটি TimeSeriesমূলত ক Map<LocalDate, Double>। আমি সমস্ত তারিখের একটি তালিকা পেতে চাই যার জন্য সময় সিরিজের কমপক্ষে একটির মান রয়েছে। flatMapউদ্ধার করতে:

list.stream().parallel()
    .flatMap(ts -> ts.dates().stream()) // for each TS, stream dates and flatmap
    .distinct()                         // remove duplicates
    .sorted()                           // sort ascending
    .collect(toList());

এটি কেবল পাঠযোগ্য নয়, তবে হঠাৎ আপনার যদি 100k উপাদানগুলির প্রক্রিয়া করার প্রয়োজন হয় তবে কেবল parallel()কোনও সংকেত কোড না লিখে পারফরম্যান্সের উন্নতি ঘটায় ।


14
উভয় উদাহরণ গ্রহণযোগ্য উত্তরের চেয়ে অনেক ভাল।
সেবাস্তিয়ান গ্রাফ

কম্পাইলার সম্পর্কে অভিযোগ পরিচয় () যেমন undefined
নির্মল

4
@ user3320018 আপনার স্ট্যাটিক আমদানি করা দরকার Function.identity
assylias

@Asslias আমি java.util.function.Function আমদানি করার চেষ্টা করেছি কিন্তু কাজ হয়নি, আমি জাভা 8 তে নতুন এবং এটি জাভা 8 নির্দিষ্ট হতে পারে বা নাও হতে পারে তবে আপনি কীভাবে আমাকে ত্রুটি অপসারণ করবেন তা আমাকে বলতে পারেন।
নির্মল

4
import static java.util.function.Function.identity;
Assylias

18

বাছাইয়ের একটি তালিকা থেকে এএসসি বাছাই করা অনন্য শব্দগুলি বের করুন:

List<String> phrases = Arrays.asList(
        "sporadic perjury",
        "confounded skimming",
        "incumbent jailer",
        "confounded jailer");

List<String> uniqueWords = phrases
        .stream()
        .flatMap(phrase -> Stream.of(phrase.split("\\s+")))
        .distinct()
        .sorted()
        .collect(Collectors.toList());
System.out.println("Unique words: " + uniqueWords);

... এবং আউটপুট:

Unique words: [confounded, incumbent, jailer, perjury, skimming, sporadic]

11

আমি কি একমাত্র অনাহুত তালিকাগুলি বিরক্তিকর খুঁজে পাই? ;-)

আসুন বস্তু দিয়ে চেষ্টা করুন। উপায় দ্বারা বাস্তব বিশ্বের উদাহরণ।

প্রদত্ত: পুনরাবৃত্ত টাস্ক উপস্থাপন করার বিষয় Ob গুরুত্বপূর্ণ টাস্ক ফিল্ড সম্পর্কে: অনুস্মারকগুলি startপ্রতিটা repeatPeriod repeatUnit(যেমন 5 ঘন্টা) পুনরুদ্ধার করতে শুরু করে repeatCountএবং মোট অনুস্মারক থাকবে (একটি শুরু সহ)।

লক্ষ্য: প্রতিটি টাস্ক অনুস্মারক অনুরোধের জন্য টাস্ক কপির একটি তালিকা অর্জন করুন।

List<Task> tasks =
            Arrays.asList(
                    new Task(
                            false,//completed sign
                            "My important task",//task name (text)
                            LocalDateTime.now().plus(2, ChronoUnit.DAYS),//first reminder(start)
                            true,//is task repetitive?
                            1,//reminder interval
                            ChronoUnit.DAYS,//interval unit
                            5//total number of reminders
                    )
            );

tasks.stream().flatMap(
        x -> LongStream.iterate(
                x.getStart().toEpochSecond(ZoneOffset.UTC),
                p -> (p + x.getRepeatPeriod()*x.getRepeatUnit().getDuration().getSeconds())
        ).limit(x.getRepeatCount()).boxed()
        .map( y -> new Task(x,LocalDateTime.ofEpochSecond(y,0,ZoneOffset.UTC)))
).forEach(System.out::println);

আউটপুট:

Task{completed=false, text='My important task', start=2014-10-01T21:35:24, repeat=false, repeatCount=0, repeatPeriod=0, repeatUnit=null}
Task{completed=false, text='My important task', start=2014-10-02T21:35:24, repeat=false, repeatCount=0, repeatPeriod=0, repeatUnit=null}
Task{completed=false, text='My important task', start=2014-10-03T21:35:24, repeat=false, repeatCount=0, repeatPeriod=0, repeatUnit=null}
Task{completed=false, text='My important task', start=2014-10-04T21:35:24, repeat=false, repeatCount=0, repeatPeriod=0, repeatUnit=null}
Task{completed=false, text='My important task', start=2014-10-05T21:35:24, repeat=false, repeatCount=0, repeatPeriod=0, repeatUnit=null}

PS: যদি কেউ একটি সহজ সমাধানের পরামর্শ দেয় তবে আমি প্রশংসা করব, আমি সর্বোপরি প্রো না।

আপডেট: @ আরবিজে বিস্তারিত ব্যাখ্যা চেয়েছিলেন তাই এখানে is মূলত ফ্ল্যাটম্যাপ স্ট্রিম থেকে সমস্ত উপাদানকে অন্য স্ট্রমের অভ্যন্তরে আউটপুট প্রবাহে রাখে। এখানে প্রচুর স্ট্রিম :)। সুতরাং, প্রারম্ভিক স্ট্রিমের প্রতিটি টাস্কের জন্য ল্যাম্বডা এক্সপ্রেশনটি x -> LongStream.iterate...দীর্ঘ মানগুলির একটি স্ট্রিম তৈরি করে যা কার্য শুরুর মুহুর্তগুলিকে উপস্থাপন করে। এই স্ট্রিমটি x.getRepeatCount()উদাহরণগুলিতে সীমাবদ্ধ । এর মানগুলি শুরু হয় x.getStart().toEpochSecond(ZoneOffset.UTC)এবং প্রতিটি পরবর্তী মান ল্যাম্বদা ব্যবহার করে গণনা করা হয় p -> (p + x.getRepeatPeriod()*x.getRepeatUnit().getDuration().getSeconds()boxed()লং র‍্যাপার উদাহরণ হিসাবে প্রতিটি দীর্ঘ মান সহ স্ট্রিমটি প্রদান করে। তারপরে সেই স্ট্রিমের প্রতিটি লংকে নতুন টাস্ক ইনস্ট্যান্সে ম্যাপ করা হয় যা আর পুনরাবৃত্তি করে না এবং এতে সম্পাদনের সঠিক সময় থাকে। এই নমুনায় ইনপুট তালিকায় একটি মাত্র টাস্ক রয়েছে। তবে ভাবুন আপনার এক হাজার আছে have তারপরে আপনার কাছে টাস্ক অবজেক্টগুলির 1000 টি স্ট্রিমের স্ট্রিম থাকবে। এবং কিflatMapএখানে কি সমস্ত স্ট্রিম থেকে সমস্ত টাস্ককে একই আউটপুট স্ট্রিমের মধ্যে রাখছে। আমি এটি বুঝতে পেরেছি এটিই। আপনার প্রশ্নের জন্য ধন্যবাদ!


8
Am I the only one who finds unwinding lists boring?+1
হোয়াইটফিন

4
এই উদাহরণটি বোঝা আমার পক্ষে সত্যিই কঠিন। :(
আরবিজেট

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

উত্তর জনতার জন্য ধন্যবাদ। তবে আমি স্ট্রিম ধারণাগুলির সাথে বেশ আছি। এখানে আমার যে সমস্যা হচ্ছে তা উদাহরণস্বরূপ। টাইম এপিআইয়ের সাথে আমি এতটা ভাল ছিলাম না, তবে এর মাধ্যমে পড়াও আমাকে এখানে কী ঘটছে তা বুঝতে সহায়তা করছে না। আমি নির্বোধ হতে পারি, তবে আপনার উত্তরের জন্য আরও কিছুটা ব্যাখ্যা দেওয়া ভাল লাগবে। এটি সত্যই আপনার উদাহরণটি বুঝতে সাহায্য করবে। আমি জানি, আমি কৌতুহলে কেবল এটিতে আবদ্ধ! :)
আরবিজেট

আশ্চর্যজনক উদাহরণ ... শুরুতে কিছুটা বোঝা, তবে একবার এটি আইডিইতে চালানো ... এত শক্তিশালী বিকল্প !! অনেক ধন্যবাদ !
ক্রিশ্চিয়ানো

2

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

http://codedestine.com/java-8-stream-flatmap-method/


2

খুব সাধারণ উদাহরণ: প্রথম বা শেষ নির্বিশেষে নামের তালিকা পেতে সম্পূর্ণ নামের একটি তালিকা বিভক্ত করুন

 List<String> fullNames = Arrays.asList("Barry Allen", "Bruce Wayne", "Clark Kent");

 fullNames.stream()
            .flatMap(fullName -> Pattern.compile(" ").splitAsStream(fullName))
            .forEach(System.out::println);

এটি মুদ্রণ করে:

Barry
Allen
Bruce
Wayne
Clark
Kent

1

প্রদত্ত এই:

  public class SalesTerritory
    {
        private String territoryName;
        private Set<String> geographicExtents;

        public SalesTerritory( String territoryName, Set<String> zipCodes )
        {
            this.territoryName = territoryName;
            this.geographicExtents = zipCodes;
        }

        public String getTerritoryName()
        {
            return territoryName;
        }

        public void setTerritoryName( String territoryName )
        {
            this.territoryName = territoryName;
        }

        public Set<String> getGeographicExtents()
        {
            return geographicExtents != null ? Collections.unmodifiableSet( geographicExtents ) : Collections.emptySet();
        }

        public void setGeographicExtents( Set<String> geographicExtents )
        {
            this.geographicExtents = new HashSet<>( geographicExtents );
        }

        @Override
        public int hashCode()
        {
            int hash = 7;
            hash = 53 * hash + Objects.hashCode( this.territoryName );
            return hash;
        }

        @Override
        public boolean equals( Object obj )
        {
            if ( this == obj ) {
                return true;
            }
            if ( obj == null ) {
                return false;
            }
            if ( getClass() != obj.getClass() ) {
                return false;
            }
            final SalesTerritory other = (SalesTerritory) obj;
            if ( !Objects.equals( this.territoryName, other.territoryName ) ) {
                return false;
            }
            return true;
        }

        @Override
        public String toString()
        {
            return "SalesTerritory{" + "territoryName=" + territoryName + ", geographicExtents=" + geographicExtents + '}';
        }

    }

এবং এই:

public class SalesTerritories
{
    private static final Set<SalesTerritory> territories
        = new HashSet<>(
            Arrays.asList(
                new SalesTerritory[]{
                    new SalesTerritory( "North-East, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "Maine", "New Hampshire", "Vermont",
                                                                                    "Rhode Island", "Massachusetts", "Connecticut",
                                                                                    "New York", "New Jersey", "Delaware", "Maryland",
                                                                                    "Eastern Pennsylvania", "District of Columbia" } ) ) ),
                    new SalesTerritory( "Appalachia, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "West-Virgina", "Kentucky",
                                                                                    "Western Pennsylvania" } ) ) ),
                    new SalesTerritory( "South-East, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "Virginia", "North Carolina", "South Carolina",
                                                                                    "Georgia", "Florida", "Alabama", "Tennessee",
                                                                                    "Mississippi", "Arkansas", "Louisiana" } ) ) ),
                    new SalesTerritory( "Mid-West, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "Ohio", "Michigan", "Wisconsin", "Minnesota",
                                                                                    "Iowa", "Missouri", "Illinois", "Indiana" } ) ) ),
                    new SalesTerritory( "Great Plains, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "Oklahoma", "Kansas", "Nebraska",
                                                                                    "South Dakota", "North Dakota",
                                                                                    "Eastern Montana",
                                                                                    "Wyoming", "Colorada" } ) ) ),
                    new SalesTerritory( "Rocky Mountain, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "Western Montana", "Idaho", "Utah", "Nevada" } ) ) ),
                    new SalesTerritory( "South-West, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "Arizona", "New Mexico", "Texas" } ) ) ),
                    new SalesTerritory( "Pacific North-West, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "Washington", "Oregon", "Alaska" } ) ) ),
                    new SalesTerritory( "Pacific South-West, USA",
                                        new HashSet<>( Arrays.asList( new String[]{ "California", "Hawaii" } ) ) )
                }
            )
        );

    public static Set<SalesTerritory> getAllTerritories()
    {
        return Collections.unmodifiableSet( territories );
    }

    private SalesTerritories()
    {
    }

}

আমরা তখন এটি করতে পারি:

System.out.println();
System.out
    .println( "We can use 'flatMap' in combination with the 'AbstractMap.SimpleEntry' class to flatten a hierarchical data-structure to a set of Key/Value pairs..." );
SalesTerritories.getAllTerritories()
    .stream()
    .flatMap( t -> t.getGeographicExtents()
        .stream()
        .map( ge -> new SimpleEntry<>( t.getTerritoryName(), ge ) )
    )
    .map( e -> String.format( "%-30s : %s",
                              e.getKey(),
                              e.getValue() ) )
    .forEach( System.out::println );
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.