{"id":17440,"date":"2023-10-08T08:08:22","date_gmt":"2023-10-08T07:08:22","guid":{"rendered":"https:\/\/www.baeldung.com\/?p=166768"},"modified":"2023-10-08T08:08:22","modified_gmt":"2023-10-08T07:08:22","slug":"partition-a-stream-in-java","status":"publish","type":"post","link":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/2023\/10\/08\/partition-a-stream-in-java\/","title":{"rendered":"Partition a Stream in Java"},"content":{"rendered":"<p><img src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2021\/09\/Java-8-Featured-1024x536.png\" class=\"webfeedsFeaturedVisual wp-post-image\" alt=\"\" decoding=\"async\" style=\"float: left; margin-right: 5px;\" loading=\"lazy\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2021\/09\/Java-8-Featured-1024x536.png 1024w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2021\/09\/Java-8-Featured-300x157.png 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2021\/09\/Java-8-Featured-768x402.png 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2021\/09\/Java-8-Featured-100x52.png 100w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2021\/09\/Java-8-Featured.png 1200w\" sizes=\"(max-width: 580px) 100vw, 580px\" \/><\/p>\n<h2 id=\"bd-overview\" data-id=\"overview\">1. Overview<\/h2>\n<div class=\"bd-anchor\" id=\"overview\"><\/div>\n<p>In this tutorial, we&#8217;ll explore various techniques for partitioning a Java 8 <em>Stream<\/em> based on a fixed maximum size.<\/p>\n<p>We&#8217;ll start by revisiting how to accomplish this with <em>List<\/em>s. Subsequently, we&#8217;ll enhance our approach by incorporating <em>Stream<\/em>-specific functionalities, such as lazy evaluation and thread safety.<\/p>\n<h2 id=\"bd-partitioning-a-list\" data-id=\"partitioning-a-list\">2. Partitioning a <em>List<\/em><\/h2>\n<div class=\"bd-anchor\" id=\"partitioning-a-list\"><\/div>\n<p><strong>There are various ways of <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/java-list-split\">partitioning a <em>List<\/em><\/a> in Java. One easy way of doing it would be to start by determining the desired number of batches based on the desired batch size and the size of the source list:<\/strong><\/p>\n<pre><code class=\"language-java\">static &lt;T&gt; Stream&lt;List&lt;T&gt;&gt; partitionList(List&lt;T&gt; source, int batchSize) {\r\n    int nrOfFullBatches = (source.size() - 1) \/ batchSize;\r\n    \/\/ ...\r\n}<\/code><\/pre>\n<p>To partition the source list into smaller sub-lists, our initial step involves computing the indices that demarcate the starting and ending points of each batch. While performing this calculation, we should keep in mind that the last batch may have a smaller size compared to the others:<\/p>\n<pre><code class=\"language-java\">int startIndex = batch * batchSize;\r\nint endIndex = (batch == nrOfFullBatches) ? source.size() : (batch + 1) * batchSize;<\/code><\/pre>\n<p>Finally, we can add some validations and cover all the corner case scenarios. For example, when the source list is empty or if <em>batchSize<\/em> is a negative number:<\/p>\n<pre><code class=\"language-java\">static &lt;T&gt; Stream&lt;List&lt;T&gt;&gt; partitionList(List&lt;T&gt; source, int batchSize) {\r\n    if (batchSize &lt;= 0) {\r\n        throw new IllegalArgumentException(String.format(&quot;The batchSize cannot be smaller than 0. Actual value: %s&quot;, batchSize));\r\n    }\r\n    if (source.isEmpty()) {\r\n        return Stream.empty();\r\n    }\r\n    int nrOfFullBatches = (source.size() - 1) \/ batchSize;\r\n    return IntStream.rangeClosed(0, nrOfFullBatches)\r\n      .mapToObj(batch -&gt; {\r\n          int startIndex = batch * batchSize;\r\n          int endIndex = (batch == nrOfFullBatches) ? source.size() : (batch + 1) * batchSize;\r\n          return source.subList(startIndex, endIndex);\r\n      });\r\n}<\/code><\/pre>\n<p>Finally, let&#8217;s test the solution. For an input list of numbers from <em>1<\/em> to <em>8<\/em> and a batch size of <em>3<\/em>, we&#8217;ll expect three sub-lists:<\/p>\n<pre><code class=\"language-java\">@Test\r\nvoid whenPartitionList_thenReturnThreeSubLists() {\r\n    List&lt;Integer&gt; source = List.of(1, 2, 3, 4, 5, 6, 7, 8);\r\n    Stream&lt;List&lt;Integer&gt;&gt; result = partitionList(source, 3);\r\n    assertThat(result).containsExactlyInAnyOrder(\r\n      List.of(1, 2, 3),\r\n      List.of(4, 5, 6),\r\n      List.of(7, 8)\r\n    );\r\n}<\/code><\/pre>\n<h2 id=\"bd-partitioning-a-parallel-stream\" data-id=\"partitioning-a-parallel-stream\">3. Partitioning a Parallel <em>Stream<\/em><\/h2>\n<div class=\"bd-anchor\" id=\"partitioning-a-parallel-stream\"><\/div>\n<p><strong><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/java-8-streams\"><em>Stream<\/em><\/a>s come with distinctive characteristics, such as lazy evaluation and the capacity for parallel processing. Embracing these features can be achieved by creating a custom <em><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/java-8-collectors\">Collector<\/a>. <\/em><\/strong><\/p>\n<p>Moreover, given that the desired return type is a list of sub-lists, we&#8217;ll also make use of certain functions already defined by <em>Collectors.toList()<\/em>, which we&#8217;ll refer to as the <em>downstream<\/em> collector:<\/p>\n<pre><code class=\"language-java\">static &lt;T&gt; List&lt;List&lt;T&gt;&gt; partitionStream(Stream&lt;T&gt; source, int batchSize) {\r\n    return source.collect(partitionBySize(batchSize, Collectors.toList()));\r\n}\r\nstatic &lt;T, A, R&gt; Collector&lt;T, ?, R&gt; partitionBySize(int batchSize, Collector&lt;List&lt;T&gt;, A, R&gt; downstream) {\r\n    return Collector.of( ... );\r\n}<\/code><\/pre>\n<p>We can create a <em>Collector<\/em> using the <em>static<\/em> factory method <em>Collector.of()<\/em>. Let&#8217;s consult the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/docs.oracle.com\/en\/java\/javase\/17\/docs\/api\/java.base\/java\/util\/stream\/Collector.html\">documentation<\/a> and see what each of the parameters represents:<\/p>\n<ul>\n<li><em>supplier<\/em> \u2013 The supplier function for the new collector<\/li>\n<li><em>accumulator<\/em> \u2013 The accumulator function for the new collector<\/li>\n<li><em>combiner<\/em> \u2013 The combiner function for the new collector<\/li>\n<li><em>finisher<\/em> \u2013 The finisher function for the new collector<\/li>\n<li><em>characteristics<\/em> \u2013 The collector characteristics for the new collector<\/li>\n<\/ul>\n<p>Now, let&#8217;s systematically walk through each of them, creating and understanding their functionality one by one.<\/p>\n<h3 id=\"bd-1-the-supplier\" data-id=\"1-the-supplier\">3.1. The <em>Supplier<\/em><\/h3>\n<div class=\"bd-anchor\" id=\"1-the-supplier\"><\/div>\n<p><strong>We&#8217;ll use a temporary object to accumulate the data and split it into batches. This accumulator is typically concealed as an implementation detail. <\/strong><\/p>\n<p><strong>Upon completion of the collection operation, we invoke the finisher function, which transforms this accumulator into the final result returned by the collector. <\/strong>The first parameter of the factory method <em>Collector.of() <\/em>will be a function that supplies an instance of our custom <em>Accumulator.<\/em><\/p>\n<p>This temporary accumulator encapsulates a list of values and the fixed batch size. Furthermore, it provides the caller with the flexibility to specify a listener that is notified when a batch reaches its capacity. Additionally, it includes a generic field to accommodate a downstream collector:<\/p>\n<pre><code class=\"language-java\">static class Accumulator&lt;T, A&gt; {\r\n    private final List&lt;T&gt; values = new ArrayList&lt;&gt;();\r\n    private final int batchSize;\r\n    private A downstreamAccumulator;\r\n    private final BiConsumer&lt;A, List&lt;T&gt;&gt; batchFullListener;\r\n    \/\/ constructor\r\n}<\/code><\/pre>\n<p>Needless to say, the accumulator remains fully encapsulated. For this reason, we&#8217;ll create it as a <em>static<\/em> inner class, and we&#8217;ll favor the package-protected access modifier.<\/p>\n<p>Now, let&#8217;s write a method that accepts a new value. After adding it to the list, if the size of the list reaches the <em>batchSize<\/em>, we&#8217;ll notify the listener and then clear the values:<\/p>\n<pre><code class=\"language-java\">void add(T value) {\r\n    values.add(value);\r\n    if (values.size() == batchSize) {\r\n        batchFullListener.accept(downstreamAccumulator, new ArrayList&lt;&gt;(values));\r\n        values.clear();\r\n    }\r\n}<\/code><\/pre>\n<p>Let&#8217;s create the <em>Supplier<\/em> that instantiates this <em>Accumulator<\/em>. When a batch is full, we&#8217;ll delegate to the downstream accumulator, in our case, the one coming from <em>Collectors.toList():<\/em><\/p>\n<pre><code class=\"language-java\">(acc, values) -&gt; downstream.accumulator().accept(acc, values)<\/code><\/pre>\n<p>Finally, we can re-write this <em>BiConsumer<\/em> using method reference and create our <em>Supplier<\/em>:<\/p>\n<pre><code class=\"language-\">Supplier&lt;Accumulator&gt; supplier =  () -&gt; new Accumulator&lt;&gt;(\r\n  batchSize,\r\n  downstream.supplier().get(),\r\n  downstream.accumulator()::accept\r\n);<\/code><\/pre>\n<h3 id=\"bd-2-the-accumulator\" data-id=\"2-the-accumulator\">3.2. The <em>Accumulator<\/em><\/h3>\n<div class=\"bd-anchor\" id=\"2-the-accumulator\"><\/div>\n<p>The second argument when creating a custom <em>Collector <\/em>will be a <em>BiConsumer <\/em>that accepts an <em>Accumulator<\/em> and the new value. In our case, we&#8217;ll simply delegate to the <em>Accumulator <\/em>and allow it to add the value to the current batch:<\/p>\n<pre><code class=\"language-java\">BiConsumer&lt;Accumulator&lt;T, A&gt;, T&gt; accumulator = (acc, value) -&gt; acc.add(value);<\/code><\/pre>\n<h3 id=\"bd-3-the-combiner\" data-id=\"3-the-combiner\">3.3. The <em>Combiner<\/em><\/h3>\n<div class=\"bd-anchor\" id=\"3-the-combiner\"><\/div>\n<p>The <em>combiner <\/em>is a function that accepts two <em>Accumulator<\/em>s and provides a way of merging them together. Firstly, we need to merge their <em>downstreamAccumulator<\/em>s using the downstream&#8217;s combiner. After that, we can stream all the values accumulated by one of the accumulators and <em>add <\/em>them to the other one:<\/p>\n<pre><code class=\"language-java\">BinaryOperator&lt;Accumulator&lt;T, A&gt;&gt; combiner = (acc1, acc2) -&gt; {\r\n    acc1.downstreamAccumulator = downstream.combiner()\r\n      .apply(acc1.downstreamAccumulator, acc2.downstreamAccumulator);\r\n    acc2.values.forEach(acc1::add);\r\n    return acc1;\r\n};<\/code><\/pre>\n<p>Let&#8217;s refactor the code and encapsulate this logic inside the <em>Accumulator<\/em> class itself:<\/p>\n<pre><code class=\"language-\">static class Accumulator&lt;T, A&gt; {\r\n    private final List&lt;T&gt; values = new ArrayList&lt;&gt;();\r\n    private final int batchSize;\r\n    private A downstreamAccumulator;\r\n    private final BiConsumer&lt;A, List&lt;T&gt;&gt; batchFullListener;\r\n    \/\/ constructor\r\n    void add(T value) {\r\n        \/\/ ...  \r\n    }\r\n    Accumulator&lt;T, A&gt; combine(Accumulator&lt;T, A&gt; other, BinaryOperator&lt;A&gt; accumulatorCombiner) {\r\n        this.downstreamAccumulator = accumulatorCombiner.apply(downstreamAccumulator, other.downstreamAccumulator);\r\n        other.values.forEach(this::add);\r\n        return this;\r\n    }\r\n}<\/code><\/pre>\n<p>This simplifies our combiner into a one-liner:<\/p>\n<pre><code class=\"language-java\">BinaryOperator&lt;Accumulator&lt;T, A&gt;&gt; combiner = (acc1, acc2) -&gt; acc1.combine(acc2, downstream.combiner());\r\n<\/code><\/pre>\n<h3 id=\"bd-4-the-finisher\" data-id=\"4-the-finisher\">3.4. The <em>Finisher<\/em><\/h3>\n<div class=\"bd-anchor\" id=\"4-the-finisher\"><\/div>\n<p><strong>As previously mentioned, we must establish a means to convert this custom <em>Accumulator<\/em> into the ultimate result: the <em>List<\/em> of <em>List<\/em>s. This is another place where we can rely on the <em>downstream<\/em> collector to aggregate all the batches into a single list.<\/strong><\/p>\n<p>Additionally, if the accumulator isn&#8217;t empty, indicating the presence of values from the last incomplete batch, we need to ensure that these values are consolidated before invoking the downstream finisher:<\/p>\n<pre><code class=\"language-java\">Function&lt;Accumulator&lt;T, A&gt;, R&gt; finisher = acc -&gt; {\r\n    if (!acc.values.isEmpty()) {\r\n        downstream.accumulator().accept(acc.downstreamAccumulator, acc.values);\r\n    }\r\n    return downstream.finisher().apply(acc.downstreamAccumulator);\r\n};<\/code><\/pre>\n<h3 id=\"bd-5-the-collector-characteristics\" data-id=\"5-the-collector-characteristics\">3.5. The <em>Collector Characteristics<\/em><\/h3>\n<div class=\"bd-anchor\" id=\"5-the-collector-characteristics\"><\/div>\n<p><strong>Our collector is designed to be thread-safe and is suitable for use with parallel streams. This means that the final reduction process occurs concurrently across multiple threads. A natural consequence of this parallel processing is the inability to guarantee the order of elements.<\/strong><\/p>\n<p><em>Collector<\/em> <em>Characteristics<\/em> can be used to optimize reduction implementations. Based on the considerations we&#8217;ve outlined, we&#8217;ll configure the characteristics parameter to utilize <em>Collector.Characteristics.UNORDERED:<\/em><\/p>\n<pre><code class=\"language-java\">static &lt;T, A, R&gt; Collector&lt;T, ?, R&gt; partitionBySize(int batchSize, Collector&lt;List, A, R&gt; downstream) {\r\n    \/\/ ...\r\n    return Collector.of(\r\n      supplier,\r\n      accumulator,\r\n      combiner,\r\n      finisher,\r\n      Collector.Characteristics.UNORDERED\r\n    );\r\n}\r\n<\/code><\/pre>\n<h3 id=\"bd-6-the-full-solution\" data-id=\"6-the-full-solution\">3.6. The Full Solution<\/h3>\n<div class=\"bd-anchor\" id=\"6-the-full-solution\"><\/div>\n<p>We now understand the roles played by each function used in collector creation. Let&#8217;s revisit the whole method before proceeding with the tests:<\/p>\n<pre><code class=\"language-java\">static &lt;T&gt; List&lt;List&lt;T&gt;&gt; partitionStream(Stream&lt;T&gt; source, int batchSize) {\r\n    return source.collect(partitionBySize(batchSize, Collectors.toList()));\r\n}\r\nstatic &lt;T, A, R&gt; Collector&lt;T, ?, R&gt; partitionBySize(int batchSize, Collector&lt;List&lt;T&gt;, A, R&gt; downstream) {\r\n    Supplier&lt;Accumulator&lt;T, A&gt;&gt; supplier = () -&gt; new Accumulator&lt;&gt;(\r\n      batchSize, \r\n      downstream.supplier().get(), \r\n      downstream.accumulator()::accept\r\n    );\r\n    BiConsumer&lt;Accumulator&lt;T, A&gt;, T&gt; accumulator = (acc, value) -&gt; acc.add(value);\r\n    BinaryOperator&lt;Accumulator&lt;T, A&gt;&gt; combiner = (acc1, acc2) -&gt; acc1.combine(acc2, downstream.combiner());\r\n    Function&lt;Accumulator&lt;T, A&gt;, R&gt; finisher = acc -&gt; {\r\n        if (!acc.values.isEmpty()) {\r\n            downstream.accumulator().accept(acc.downstreamAccumulator, acc.values);\r\n        }\r\n        return downstream.finisher().apply(acc.downstreamAccumulator);\r\n    };\r\n    \r\n    return Collector.of(supplier, accumulator, combiner, finisher, Collector.Characteristics.UNORDERED);\r\n}<\/code><\/pre>\n<p><strong>During testing, we&#8217;ll no longer be able to assert the values within each batch. Consequently, our assertions will focus solely on verifying the count and sizes of the batches.<\/strong> For instance, when partitioning a parallel stream that contains integers between <em>1<\/em> and <em>8<\/em> with a <em>batchSize<\/em> of <em>3<\/em>, we&#8217;ll generate two complete batches, each containing three elements, and one batch with two elements:<\/p>\n<pre><code class=\"language-java\">@Test\r\nvoid whenPartitionStream_thenReturnThreeSubLists() {\r\n    Stream&lt;Integer&gt; source = Stream.of(1, 2, 3, 4, 5, 6, 7, 8).parallel();\r\n    List&lt;List&lt;Integer&gt;&gt; result = partitionStream(source, 3);\r\n    assertThat(result)\r\n      .hasSize(3)\r\n      .satisfies(batch -&gt; assertThat(batch).hasSize(3), atIndex(0))\r\n      .satisfies(batch -&gt; assertThat(batch).hasSize(3), atIndex(1))\r\n      .satisfies(batch -&gt; assertThat(batch).hasSize(2), atIndex(2));\r\n}<\/code><\/pre>\n<h2 id=\"bd-partitioning-a-stream-using-guava\" data-id=\"partitioning-a-stream-using-guava\">4. Partitioning a <em>Stream<\/em> Using Guava<\/h2>\n<div class=\"bd-anchor\" id=\"partitioning-a-stream-using-guava\"><\/div>\n<p><strong>To avoid potential errors, we can opt for the utilization of a proven third-party library<\/strong> rather than building a thread-safe <em>Collector<\/em> from scratch. For instance, <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/guava-guide\">Google&#8217;s Guava<\/a> provides an elegant and concise way for partitioning a <em>Stream<\/em> into an <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/java-iterator-vs-iterable#iterable-interface\"><em>Iterable<\/em><\/a> comprising <em>List<\/em>s of the same data type.<\/p>\n<p>Firstly, let&#8217;s add the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/mvnrepository.com\/artifact\/com.google.guava\/guava\">dependency<\/a> to our <em>pom.xml<\/em>:<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\r\n    &lt;groupId&gt;com.google.guava&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;guava&lt;\/artifactId&gt;\r\n    &lt;version&gt;32.1.2-jre&lt;\/version&gt;\r\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>Now, we can simply use the <em>static<\/em> method <em>Iterables.partition(). <\/em>This function accepts an <em>Iterable<\/em> and the desired batch size as its parameters:<\/p>\n<pre><code class=\"language-java\">static &lt;T&gt; Iterable&lt;List&lt;T&gt;&gt; partitionUsingGuava(Stream&lt;T&gt; source, int batchSize) {\r\n    return Iterables.partition(source::iterator, batchSize);\r\n}<\/code><\/pre>\n<p>The only distinction in our testing approach lies in the altered return type, now an <em>Iterable<\/em>. To assert the batch sizes, we&#8217;ll gather all elements of the <em>Iterable<\/em> into an <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/java-arraylist\"><em>ArrayList<\/em><\/a>. Besides this adjustment, the testing procedure remains unchanged:<\/p>\n<pre><code class=\"language-java\">@Test\r\nvoid whenPartitionParallelStreamWithGuava_thenReturnThreeSubLists() {\r\n    Stream&lt;Integer&gt; source = Stream.of(1, 2, 3, 4, 5, 6, 7, 8).parallel();\r\n    Iterable&lt;List&lt;Integer&gt;&gt; result = partitionUsingGuava(source, 3);\r\n    assertThat(result)\r\n      .map(ArrayList::new)\r\n      .hasSize(3)\r\n      .satisfies(batch -&gt; assertThat(batch).asList().hasSize(3), atIndex(0))\r\n      .satisfies(batch -&gt; assertThat(batch).asList().hasSize(3), atIndex(1))\r\n      .satisfies(batch -&gt; assertThat(batch).asList().hasSize(2), atIndex(2));\r\n}<\/code><\/pre>\n<h2 id=\"bd-conclusion\" data-id=\"conclusion\">5. Conclusion<\/h2>\n<div class=\"bd-anchor\" id=\"conclusion\"><\/div>\n<p>In this article, we explored various ways of partitioning a <em>Stream<\/em> in Java. We started by recalling how we can split a <em>List <\/em>into smaller sub-lists of fixed values of fixed sizes. Following that, we discussed the advantages of <em>Stream<\/em>s and parallel <em>Stream<\/em>s<em>, <\/em>and we created our own custom <em>Collector <\/em>for them.<\/p>\n<p>Finally, we ventured into Guava&#8217;s API, which enables us to accomplish the same functionality effortlessly using the <em>static<\/em> method <em>Iterables.partition().<\/em><\/p>\n<p>As always, the complete source code for the examples is available <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/github.com\/eugenp\/tutorials\/tree\/master\/core-java-modules\/core-java-streams-5\">over on GitHub<\/a>.<\/p>\n<p><Img align=\"left\" border=\"0\" height=\"1\" width=\"1\" alt=\"\" style=\"border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;\" hspace=\"0\" src=\"https:\/\/feeds.feedblitz.com\/~\/i\/798346622\/0\/baeldung\"><\/p>\n<div style=\"clear:both;padding-top:0.2em;\"><a title=\"Like on Facebook\" href=\"https:\/\/feeds.feedblitz.com\/_\/28\/798346622\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/fblike20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Pin it!\" href=\"https:\/\/feeds.feedblitz.com\/_\/29\/798346622\/baeldung,https%3A%2F%2Fwww.baeldung.com%2Fwp-content%2Fuploads%2F2021%2F09%2FJava-8-Featured-1024x536.png\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/pinterest20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Tweet This\" href=\"https:\/\/feeds.feedblitz.com\/_\/24\/798346622\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/twitter20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Subscribe by email\" href=\"https:\/\/feeds.feedblitz.com\/_\/19\/798346622\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/email20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Subscribe by RSS\" href=\"https:\/\/feeds.feedblitz.com\/_\/20\/798346622\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/rss20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a rel=\"NOFOLLOW\" title=\"View Comments\" href=\"https:\/\/www.baeldung.com\/java-partition-stream#respond\"><img decoding=\"async\" height=\"20\" style=\"border:0;margin:0;padding:0;\" src=\"https:\/\/assets.feedblitz.com\/i\/comments20.png\"><\/a>&#160;<a title=\"Follow Comments via RSS\" href=\"https:\/\/www.baeldung.com\/java-partition-stream\/feed\"><img decoding=\"async\" height=\"20\" style=\"border:0;margin:0;padding:0;\" src=\"https:\/\/assets.feedblitz.com\/i\/commentsrss20.png\"><\/a>&#160;<\/div>\n\n<h2><b>Commercials Cooperation Advertisements:<\/b><\/h2>\r\n<p><br>(1) IT Teacher IT Freelance<br> <\/p>\r\n<a href=https:\/\/itteacheritfreelance.hk\/wordpress><img src=http:\/\/gamefootballmobileanimeiphone.com\/wp-content\/uploads\/2023\/09\/ITTeacherITFreelance-Website.png alt=IT\u96fb\u8166\u88dc\u7fd2 java\u88dc\u7fd2 \u70ba\u5927\u5bb6\u914d\u5c0d\u96fb\u8166\u88dc\u7fd2,IT freelance, \u79c1\u4eba\u8001\u5e2b, PHP\u88dc\u7fd2,CSS\u88dc\u7fd2,XML,Java\u88dc\u7fd2,MySQL\u88dc\u7fd2,graphic design\u88dc\u7fd2,\u4e2d\u5c0f\u5b78ICT\u88dc\u7fd2,\u4e00\u5c0d\u4e00\u79c1\u4eba\u88dc\u7fd2\u548cFreelance\u81ea\u7531\u5de5\u4f5c\u914d\u5c0d\u3002\/><\/a><p><a href=https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/findteacher>\u7acb\u523b\u8a3b\u518a\u53ca\u5831\u540d\u96fb\u8166\u88dc\u7fd2\u8ab2\u7a0b\u5427! <\/a><br>\r\n\r\n\u7535\u5b50\u8ba1\u7b97\u673a -\u6559\u80b2 -IT \u96fb\u8166\u73ed\u201d ( IT\u96fb\u8166\u88dc\u7fd2 ) \u63d0\u4f9b\u4e00\u500b\u65b9\u4fbf\u7684\u7535\u5b50\u8ba1\u7b97\u673a \u6559\u80b2\u5e73\u53f0, \u70ba\u5927\u5bb6\u914d\u5c0d\u4fe1\u606f\u6280\u672f, \u96fb\u8166 \u8001\u5e2b, IT freelance \u548c programming expert. \u8b93\u5927\u5bb6\u65b9\u4fbf\u5730\u5c31\u80fd\u627e\u5230\u5408\u9069\u7684\u96fb\u8166\u88dc\u7fd2, \u96fb\u8166\u73ed, \u5bb6\u6559, \u79c1\u4eba\u8001\u5e2b.  <br>\r\n\r\nWe are a education and information platform which you can find a IT private tutorial teacher or freelance. <br>\r\n\r\nAlso we provide different information about information technology, Computer, programming, mobile, Android, apple, game, movie, anime, animation\u2026 \r\n<\/p>\n<p><br>(2) ITSec<br> <\/p><a href=https:\/\/itsec.vip><img src=http:\/\/gamefootballmobileanimeiphone.com\/wp-content\/uploads\/2023\/09\/ITSec-Main-Promotion-Image.png alt= https:\/\/itsec.vip\/\r\nSecure Your Computers from Cyber Threats and mitigate risks with professional services to defend Hackers.  \r\nITSec provide IT Security and Compliance Services, including IT Compliance Services, Risk Assessment, IT Audit, Security Assessment and Audit, ISO 27001 Consulting and Certification, GDPR Compliance Services, Privacy Impact Assessment (PIA), Penetration test, Ethical Hacking, Vulnerabilities scan, IT Consulting, Data Privacy Consulting, Data Protection Services, Information Security Consulting, Cyber Security Consulting, Network Security Audit, Security Awareness Training.\/><\/a> \r\n<br><br> \r\n<p><a href=https:\/\/itsec.vip>www.ITSec.vip<\/a> <br> <br> \r\n<p><a href=https:\/\/sraa.com.hk>www.Sraa.com.hk<\/a> <br> <br> \r\n<p><a href=https:\/\/itsec.hk>www.ITSec.hk<\/a> <br> <br> \r\n<p><a href=https:\/\/penetrationtest.hk>www.Penetrationtest.hk<\/a> <br> <br> \r\n<p><a href=https:\/\/itseceu.uk>www.ITSeceu.uk<\/a> <br> <br> \r\nSecure Your Computers from Cyber Threats and mitigate risks with professional services to defend Hackers. <br><br>\r\nITSec provide IT Security and Compliance Services, including IT Compliance Services, Risk Assessment, IT Audit, Security Assessment and Audit, ISO 27001 Consulting and Certification, GDPR Compliance Services, Privacy Impact Assessment (PIA), Penetration test, Ethical Hacking, Vulnerabilities scan, IT Consulting, Data Privacy Consulting, Data Protection Services, Information Security Consulting, Cyber Security Consulting, Network Security Audit, Security Awareness Training. \r\n<br><br>Contact us right away. <br><br>Email (Prefer using email to contact us): <br>SalesExecutive@ITSec.vip<\/p>","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2021\/09\/Java-8-Featured-1024x536.png\" class=\"webfeedsFeaturedVisual wp-post-image\" alt=\"\" loading=\"lazy\"><\/p>\n<p>Explore various ways of partitioning a Stream in Java.<\/p>\n<div><a title=\"Like on Facebook\" href=\"https:\/\/feeds.feedblitz.com\/_\/28\/798346622\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/fblike20.png\"><\/a>\u00a0<a title=\"Pin it!\" href=\"https:\/\/feeds.feedblitz.com\/_\/29\/798346622\/baeldung,https%3A%2F%2Fwww.baeldung.com%2Fwp-content%2Fuploads%2F2021%2F09%2FJava-8-Featured-1024x536.png\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/pinterest20.png\"><\/a>\u00a0<a title=\"Tweet This\" href=\"https:\/\/feeds.feedblitz.com\/_\/24\/798346622\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/twitter20.png\"><\/a>\u00a0<a title=\"Subscribe by email\" href=\"https:\/\/feeds.feedblitz.com\/_\/19\/798346622\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/email20.png\"><\/a>\u00a0<a title=\"Subscribe by RSS\" href=\"https:\/\/feeds.feedblitz.com\/_\/20\/798346622\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/rss20.png\"><\/a>\u00a0<a rel=\"NOFOLLOW\" title=\"View Comments\" href=\"https:\/\/www.baeldung.com\/java-partition-stream#respond\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/comments20.png\"><\/a>\u00a0<a title=\"Follow Comments via RSS\" href=\"https:\/\/www.baeldung.com\/java-partition-stream\/feed\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/commentsrss20.png\"><\/a>\u00a0<\/div>\n","protected":false},"author":865,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[22],"tags":[61,122,127,129,124,128,125,132,131,133,126,130,123,66,94,88,97,56,64,65,60,112,40,75,95,104,33,120,105,101,98,115,30,29,41,86,70,69,68,72,71,26,118,108,87,46,55,48,52,54,51,50,83,62,58,57,109,35,59,63,85,79,82,96,80,27,81,114,44,42,43,45,38,39,110,117,100,111,116,73,89,90,92,91,93,84,78,37,102,34,36,77,67,74,99,113,119,28,121,32,47,49,53,103,31,76],"class_list":["post-17440","post","type-post","status-publish","format-standard","hentry","category-mobile","tag-airpods","tag-anime","tag-anime-characters","tag-anime-cosplay","tag-anime-edits","tag-anime-merchandise","tag-anime-movies","tag-anime-news","tag-anime-recommendations","tag-anime-reviews","tag-anime-series","tag-anime-streaming","tag-animes","tag-app-store","tag-app-store-samsung","tag-appgallery","tag-appgallery-oneplus","tag-apple","tag-apple-music","tag-apple-tv","tag-apple-watch","tag-bbc-sport","tag-best-mobile-games","tag-bixby","tag-bixby-xiaomi","tag-champions-league","tag-cyberpunk","tag-cyberpunk-2077","tag-fantasy-football","tag-fifa","tag-football","tag-formula-1","tag-fortnite","tag-free-fire","tag-free-mobile-games","tag-freebuds-pro","tag-galaxy-a52","tag-galaxy-note-20","tag-galaxy-s21","tag-galaxy-watch-4","tag-galaxy-z-fold-3","tag-game","tag-games","tag-golf","tag-harmonyos","tag-how-to-backup-iphone","tag-how-to-factory-reset-iphone","tag-how-to-reset-iphone","tag-how-to-restore-iphone","tag-how-to-unlock-iphone","tag-how-to-unlock-iphone-5","tag-how-to-unlock-iphone-6","tag-huawei","tag-ios","tag-ipad","tag-iphone","tag-live-soccer","tag-lol","tag-macbook","tag-macos","tag-mate-40-pro","tag-mi-11-lite","tag-mi-home-security-camera-basic-1080p","tag-mi-home-security-camera-basic-1080p-huawei","tag-mi-smart-band-6","tag-minecraft","tag-miui","tag-mlb-scores","tag-mobile-game-design","tag-mobile-game-development","tag-mobile-game-marketing","tag-mobile-game-monetization","tag-mobile-games","tag-mobile-gaming","tag-nba-scores","tag-nba-standings","tag-nfl","tag-nfl-scores","tag-nhl-scores","tag-one-ui","tag-oneplus","tag-oneplus-9-pro","tag-oneplus-buds-pro","tag-oneplus-nord-ce-5g","tag-oxygenos","tag-p40-pro-plus","tag-poco-x3-pro","tag-pokemon","tag-premier-league","tag-pubg","tag-pubg-mobile","tag-redmi-note-10-pro","tag-samsung","tag-samsung-pay","tag-soccer","tag-sports","tag-steam","tag-steeam","tag-top-10-anime","tag-valorant","tag-when-do-the-iphone-7-come-out","tag-when-does-the-iphone-7-come-out","tag-when-is-the-iphone-7-coming-out","tag-world-cup","tag-xbox-series-x","tag-xiaomi"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/posts\/17440","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/users\/865"}],"replies":[{"embeddable":true,"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/comments?post=17440"}],"version-history":[{"count":1,"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/posts\/17440\/revisions"}],"predecessor-version":[{"id":17441,"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/posts\/17440\/revisions\/17441"}],"wp:attachment":[{"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/media?parent=17440"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/categories?post=17440"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gamefootballmobileanimeiphone.com\/index.php\/wp-json\/wp\/v2\/tags?post=17440"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}