Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print a list by adding a new line after every 3rd element in a list in java lambda expression?

Suppose I have a list as below

Collection<?> mainList = new ArrayList<String>();
mainList=//some method call//

Currently, I am displaying the elements in the list as

System.out.println(mainList.stream().map(Object::toString).collect(Collectors.joining(",")).toString());

And I got the result as

a,b,c,d,e,f,g,h,i

How to print this list by adding a new line after every 3rd element in a list in java, so that it will print the result as below

a,b,c
d,e,f
g,h,i

Note: This is similar to How to Add newline after every 3rd element in arraylist in java?.But there formatting the file is done while reading itself. I want to do it while printing the output.

like image 396
Anonymous Avatar asked Dec 18 '22 04:12

Anonymous


2 Answers

If you want to stick to Java Stream API then your problem can be solved by partitioning initial list to sublists of size 3 and then representing each sublist as a String and joining results with \n.

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

final class PartitionListExample {

    public static void main(String[] args) {

        final Collection<String> mainList = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i");
        final AtomicInteger idx = new AtomicInteger(0);
        final int size = 3;

        // Partition a list into list of lists size 3
        final Collection<List<String>> rows = mainList.stream()
                .collect(Collectors.groupingBy(
                        it -> idx.getAndIncrement() / size
                ))
                .values();

        // Write each row in the new line as a string
        final String result = rows.stream()
                .map(row -> String.join(",", row))
                .collect(Collectors.joining("\n"));

        System.out.println(result);
    }
}

There are 3rd party libraries that provide utility classes that makes list partitioning easier (e.g. Guava or Apache Commons Collections) but this solution is built on Java 8 SDK only.

What it does is:

  • firstly we collect all elements by grouping by assigned row index and we store values as a list (e.g. {0=[a,b,c],1=[d,e,f],2=[g,h,i]}
  • then we take a list of all values like [[a,b,c],[d,e,f],[g,h,i]]
  • finally we represent list of lists as a String where each row is separated by \n

Output Demo

Running following program will print to console following output:

a,b,c
d,e,f
g,h,i

Getting more from following example

Alnitak played even more with following example and came up with a shorter solution by utilizing Collectors.joining(",") in .groupingBy collector and using String.join("\n", rows) in the end instead of triggering another stream reduction.

        final Collection<String> rows = mainList.stream()
                .collect(Collectors.groupingBy(
                        it -> idx.getAndIncrement() / size,
                        Collectors.joining(",")
                ))
                .values();

        // Write each row in the new line as a string
        final String result = String.join("\n", rows);

        System.out.println(result);
    }

Final note

Keep in mind that this is not the most efficient way to print list of elements in your desired format. But partitioning list of any elements gives you flexibility if it comes to creating final result and is pretty easy to read and understand.

like image 87
Szymon Stepniak Avatar answered Dec 20 '22 17:12

Szymon Stepniak


A side remark : in your actual code, map(Object::toString) could be removed if you replace

Collection<?> mainList = new ArrayList<String>(); by

Collection<String> mainList = new ArrayList<String>();.

If you manipulate Strings, create a Collection of String rather than Collection of ?.


But there formatting the file is done while reading itself.I want to do it while printing the output.

After gotten the joined String, using replaceAll("(\\w*,\\w*,\\w*,)", "$1" + System.lineSeparator()) should do the job.
Iit will search and replace all series of 3 characters or more separated by a , character by the same thing ($1-> group capturing) but by concatenating it with a line separator.

Besides this :

String collect = mainList.stream().collect(Collectors.joining(","));    

could be simplified by :

String collect = String.join(",", mainList);    

Sample code :

public static void main(String[] args) {
  Collection<String> mainList = Arrays.asList("a","b","c","d","e","f","g","h","i", "j");
  String formattedValues = String.join(",", mainList).replaceAll("(\\w*,\\w*,\\w*,)", "$1" + System.lineSeparator());
  System.out.println(formattedValues);
}

Output :

a,b,c,

d,e,f,

g,h,i,

j

like image 25
davidxxx Avatar answered Dec 20 '22 18:12

davidxxx