1, What is stream?
in Java8, Collection adds two stream methods, Stream() and parallelStream(), which are defined in Java util. Stream package. Stream is mainly used to replace some Collection operations. Each stream represents a value sequence. Stream provides a series of common aggregation operations on which various operations can be performed. The Collection class library also provides a convenient way for us to use collections, arrays and other data structures in the way of operation flow.
2, stream operation classification
Stream operation classification | ||
---|---|---|
Intermediate operation | Stateless | unordered(), filter(), map(), mapToInt(), mapToLong(), mapToDouble(), flatMap(), flatMapToInt(), flatMapToLong() , flatMapToDouble(), peek() |
Stateful | distinct(), sorted(), limit(), skip() | |
Terminate operation | Non short circuit operation | forEach(), forEachOrdered(), toArray(), reduce(), collect(), max(), min(), count() |
Short circuit operation | anyMatch(), allMatch(), noneMatch(), findFirst(), findAny() |
Intermediate operation
when the data in the data source is pipelined, all operations on the data in this process are called "intermediate operations". Intermediate operations will still return a stream object, so multiple intermediate operations can be connected in series to form a pipeline. Stream provides many types of intermediate operations, such as filter, distinct, map, sorted and so on.
intermediate operations can be divided into stateless and Stateful operations. Stateless means that the processing of elements is not affected by the previous elements, and Stateful means that the operation can continue only after all elements are obtained.
Terminate operation
after all intermediate operations are completed, if you want to remove the data from the pipeline, you need to perform terminal operations. For terminal operations, stream can directly provide the result of an intermediate operation, or convert the result into a specific collection, array, String, etc.
termination operations can be divided into short circuiting and unshort circuiting operations. Short circuit means that the final result can be obtained when meeting some qualified elements, and non short circuit means that all elements must be processed to obtain the final result.
Common operation types
Operation type | effect |
---|---|
map() | The elements in the flow are processed again to form a new flow, and each element in the flow is mapped to another element |
filter() | The new stream generated from the returned result contains only the data that meets the filter criteria |
limit() | Returns a Stream of a specified number of elements. The first n elements in the Stream are returned |
skip() | In contrast to limit(), skip (take out) the first few elements and return a stream. If the elements in the stream are less than or equal to n, an empty stream will be returned |
sorted() | Sort the elements in the stream in a natural way |
distinct() | Output after de duplication of elements in the stream |
peek() | Each element in the stream performs an operation and returns a new stream. The returned stream still contains the elements in the original stream |
3, Use of stream
Sample data
public class StreamTest { @Data @AllArgsConstructor static class Student { private String classNo; private String name; private String enName; private Integer age; private String sex; private Integer totalScore; } public static void main(String[] args) { Student a = new Student("1 class", "Zhang San", "zs", 18, "male", 299); Student b = new Student("1 class", "Xiao Ming Wang", "xm", 17, "male", 278); Student c = new Student("3 class", "Zhou Dahong", "", 18, "female", 255); Student d = new Student("1 class", "Liu Laoliu", "lll", 19, "male", 300); Student e = new Student("2 class", "Li Xiaohua", "", 18, "female", 281); Student f = new Student("4 class", "Chen Huahua", "", 17, "female", 281); Student g = new Student("2 class", "bachelor", "wlw", 20, "male", 229); Student h = new Student("3 class", "Li Si", "ls", 16, "male", 267); Student i = new Student("2 class", "Lin Dazhuang", "", 17, "male", 297); List<Student> list = Arrays.asList(a, b, c, d, e, f, g, h, i); //Specific operation } }
3.1.forEach()
Traversal set
list.forEach(System.out::println);
3.2.map()
(1) Take out the names of all students
List<String> nameList = list.stream() .map(Student::getName) .collect(Collectors.toList());
(2) Lowercase to uppercase
List<String> lowCaseList = new ArrayList<>(); lowCaseList.add("dog"); lowCaseList.add("cat"); lowCaseList.add("tiger"); lowCaseList.add("lion"); List<String> upperCaseList = lowCaseList.stream() .map(String::toUpperCase) .collect(Collectors.toList()); //Print upperCaseList.forEach(System.out::println);
DOG
CAT
TIGER
LION
3.3.filter()
(1) Take out students older than 18
List<Student> studentList = list.stream() .filter(s -> s.getAge() > 18) .collect(Collectors.toList());
(2) Multi condition filtering: get the information set of boys in class 1
List<Student> studentList = list.stream() .filter(student -> (student.getClassNo().equals("1 class") && (student.getSex().equals("male")))) .collect(Collectors.toList()); //Print studentList.forEach(System.out::println);
StreamTest. Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalScore=299)
StreamTest. Student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalScore=278)
StreamTest. Student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalScore=300)
(3) Get student information surnamed Wang
List<Student> studentList = list.stream() .filter(s -> s.getName().startsWith("king")) .collect(Collectors.toList()); //Print studentList.forEach(System.out::println);
StreamTest. Student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalScore=278)
StreamTest. Student (classno = class 2, name = Wang Laowu, enName=wlw, age=20, sex = male, totalScore=229)
3.3.distinct()
Take out the list of all non repeated student scores
List<Integer> scoreList = list.stream() .map(Student::getTotalScore) .distinct() .collect(Collectors.toList());
3.4.allMatch()
Are all students above 250 (full match)
boolean flag = list.stream() .map(Student::getTotalScore) .allMatch(s -> s > 250);
3.5.anyMatch()
Are there any students older than 20 years old among all students (arbitrary matching)
boolean flag = list.stream() .map(Student::getAge) .anyMatch(n -> n > 21);
3.6.noneMatch()
Are all students under the age of 20 (no match)
boolean flag = list.stream() .map(Student::getAge) .noneMatch(n -> n > 20);
3.7.sorted()
(1) Sort by student age (default ascending order)
List<Student> list = Arrays.asList(a, b, c, d, e, f, g, h, i); List<Student> sortList = list.stream() .sorted(Comparator.comparingInt(Student::getAge)) .collect(Collectors.toList()); //Print sortList.forEach(System.out::println);
StreamTest. Student (classno = class 3, name = Li Si, enName=ls, age=16, sex = male, totalScore=267)
StreamTest. Student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalScore=278)
StreamTest. Student (classno = class 4, name = Chen Huahua, enName=, age=17, sex = female, totalScore=281)
StreamTest. Student (classno = class 2, name = Lin Dazhuang, enName=, age=17, sex = male, totalScore=297)
StreamTest. Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalScore=299)
StreamTest. Student (classno = class 3, name = Zhou Dahong, enName=, age=18, sex = female, totalScore=255)
StreamTest. Student (classno = class 2, name = Li Xiaohua, enName=, age=18, sex = female, totalScore=281)
StreamTest. Student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalScore=300)
StreamTest. Student (classno = class 2, name = Wang Laowu, enName=wlw, age=20, sex = male, totalScore=229)
(2) Sort students in descending order of age (just add. reversed())
List<Student> sortList = list.stream() .sorted(Comparator.comparingInt(Student::getAge).reversed()) .collect(Collectors.toList()); //Print sortList.forEach(System.out::println);
StreamTest. Student (classno = class 2, name = Wang Laowu, enName=wlw, age=20, sex = male, totalScore=229)
StreamTest. Student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalScore=300)
StreamTest. Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalScore=299)
StreamTest. Student (classno = class 3, name = Zhou Dahong, enName=, age=18, sex = female, totalScore=255)
StreamTest. Student (classno = class 2, name = Li Xiaohua, enName=, age=18, sex = female, totalScore=281)
StreamTest. Student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalScore=278)
StreamTest. Student (classno = class 4, name = Chen Huahua, enName=, age=17, sex = female, totalScore=281)
StreamTest. Student (classno = class 2, name = Lin Dazhuang, enName=, age=17, sex = male, totalScore=297)
StreamTest. Student (classno = class 3, name = Li Si, enName=ls, age=16, sex = male, totalScore=267)
(3) Multi condition sorting: sort students in descending order according to their age and in ascending order according to their scores
List<Student> sortList = list.stream() .sorted(Comparator.comparingInt(Student::getAge).reversed().thenComparingInt(Student::getTotalScore)) .collect(Collectors.toList()); //Print sortList.forEach(System.out::println);
StreamTest. Student (classno = class 2, name = Wang Laowu, enName=wlw, age=20, sex = male, totalScore=229)
StreamTest. Student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalScore=300)
StreamTest. Student (classno = class 3, name = Zhou Dahong, enName=, age=18, sex = female, totalScore=255)
StreamTest. Student (classno = class 2, name = Li Xiaohua, enName=, age=18, sex = female, totalScore=281)
StreamTest. Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalScore=299)
StreamTest. Student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalScore=278)
StreamTest. Student (classno = class 4, name = Chen Huahua, enName=, age=17, sex = female, totalScore=281)
StreamTest. Student (classno = class 2, name = Lin Dazhuang, enName=, age=17, sex = male, totalScore=297)
StreamTest. Student (classno = class 3, name = Li Si, enName=ls, age=16, sex = male, totalScore=267)
3.7.skip() + limit() paging
According to the descending order of students' total scores, and obtain the data on page 2, with 3 data on each page (the initial page is 1)
int pageNo = 2;//Suppose you get the second page of data int pageSize = 3;//3 tone data per page int skip = (pageNo - 1) * pageSize;//The initial page starts from 1 and the calculation starts from the article List<Student> pageList = list.stream() .sorted(Comparator.comparingInt(Student::getTotalScore).reversed()) .skip(skip) .limit(pageSize) .collect(Collectors.toList()); //Print pageList.forEach(System.out::println);
StreamTest. Student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalScore=300)
StreamTest. Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalScore=299)
StreamTest. Student (classno = class 2, name = Lin Dazhuang, enName=, age=17, sex = male, totalScore=297)
3.7. grouping
(1) Group according to class
Map<String, List<Student>> group = list.stream() .collect(Collectors.groupingBy(Student::getClassNo)); //Print group.forEach((k, v) -> System.out.println("k:" + k + ",v:" + v.toString()));
k: Class 4, V: [streamtest. Student (classno = class 4, name = Chen Huahua, enName=, age=17, sex = female, totalScore=281)]
k: Class 3, V: [streamtest. Student (classno = class 3, name = Zhou Dahong, enName=, age=18, sex = female, totalscore = 255), streamtest. Student (classno = class 3, name = Li Si, enName=ls, age=16, sex = male, totalScore=267)]
k: Class 2, V: [streamtest. Student (classno = class 2, name = Li Xiaohua, enName=, age=18, sex = female, totalscore = 281), streamtest. Student (classno = class 2, name = Wang Laowu, enName=wlw, age=20, sex = male, totalscore = 229), streamtest. Student (classno = class 2, name = Lin Dazhuang, enName=, age=17, sex = male, totalScore=297)]
k: Class 1, V: [streamtest.student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalscore = 299), streamtest.student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalscore = 278), streamtest.student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalScore=300)]
(2) Group according to the class, and sort in descending order according to the group
Map<String, List<Student>> group = list.stream() .sorted(Comparator.comparing(Student::getTotalScore).reversed()) .collect(Collectors.groupingBy(Student::getClassNo)); //Print group.forEach((k, v) -> System.out.println("k:" + k + ",v:" + v.toString()));
k: Class 4, V: [streamtest. Student (classno = class 4, name = Chen Huahua, enName=, age=17, sex = female, totalScore=281)]
k: Class 3, V: [streamtest. Student (classno = class 3, name = Li Si, enName=ls, age=16, sex = male, totalscore = 267), streamtest. Student (classno = class 3, name = Zhou Dahong, enName=, age=18, sex = female, totalScore=255)]
k: Class 2, V: [streamtest. Student (classno = class 2, name = Lin Dazhuang, enName=, age=17, sex = male, totalscore = 297), streamtest. Student (classno = class 2, name = Li Xiaohua, enName=, age=18, sex = female, totalscore = 281), streamtest. Student (classno = class 2, name = Wang Laowu, enName=wlw, age=20, sex = male, totalScore=229)]
k: Class 1, V: [streamtest.student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalscore = 300), streamtest.student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalscore = 299), streamtest.student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalScore=278)]
(3) Multi condition grouping (group the boys and girls in the class according to the class)
Map<String, Map<String, List<Student>>> map = list.stream() .collect(Collectors.groupingBy(Student::getClassNo, Collectors.groupingBy(Student::getSex))); //Print map.forEach((k, v) -> System.out.println("k= " + k + ", v= " + v.toString()));
K = class 4, v = {female = [streamtest. Student (classno = class 4, name = Chen Huahua, enName=, age=17, sex = female, totalScore=281)]}
K = class 3, v = {female = [streamtest. Student (classno = class 3, name = Zhou Dahong, enName=, age=18, sex = female, totalScore=255)], male = [streamtest. Student (classno = class 3, name = Li Si, enName=ls, age=16, sex = male, totalScore=267)]}
K = class 2, v = {female = [streamtest. Student (classno = class 2, name = Li Xiaohua, enName=, age=18, sex = female, totalScore=281)], male = [streamtest. Student (classno = class 2, name = Wang Laowu, enName=wlw, age=20, sex = male, totalscore = 229), streamtest. Student (classno = class 2, name = Lin Dazhuang, enName=, age=17, sex = male, totalScore=297)]}
K = class 1, v = {male = [streamtest. Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalscore = 299), streamtest. Student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalscore = 278), streamtest. Student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalScore=300)]}
3.8. Statistics
Find the minimum value, maximum value, sum of all scores and average value of students' scores respectively
int min = list.stream().mapToInt(Student::getTotalScore).min().getAsInt(); //Maximum int max = list.stream().mapToInt(Student::getTotalScore).max().getAsInt(); //Total score int sum = list.stream().mapToInt(Student::getTotalScore).sum(); //metering long count = list.stream().mapToInt(Student::getTotalScore).count(); //average value double average = list.stream().mapToInt(Student::getTotalScore).average().getAsDouble(); //How to make the average value safer: increase the default value of orElse() to prevent the list from being empty double average1 = list.stream().mapToInt(Student::getTotalScore).average().orElse(0.0); System.out.println("max: " + max); System.out.println("min: " + min); System.out.println("sum: " + sum); System.out.println("count: " + count); System.out.println("average: " + average); System.out.println("average1: " + average1);
max: 300
min: 229
sum: 2487
count: 9
average: 276.3333333333333
average1: 276.3333333333333
Using the statistics collector
IntSummaryStatistics statistics = list.stream() .mapToInt(Student::getTotalScore) .summaryStatistics(); System.out.println("max: " + statistics.getMax()); System.out.println("min: " + statistics.getMin()); System.out.println("sum: " + statistics.getSum()); System.out.println("count: " + statistics.getCount()); System.out.println("average: " + statistics.getAverage());
max: 300
min: 229
sum: 2487
count: 9
average: 276.3333333333333
3.9. String splicing
Put all the students' names together and divide them with ','
String str = list.stream() .map(Student::getName) .collect(Collectors.joining(",")); System.out.println(str);
Zhang San, Wang Xiaoming, Zhou Dahong, Liu Laoliu, Li Xiaohua, Chen Huahua, Wang Laowu, Li Si, Lin Dazhuang
3.10. Set conversion
list to set
Set<String> set = list.stream() .map(Student::getClassNo) .collect(Collectors.toSet()); set.forEach(System.out::println);
Class 4
Class 3
Class 2
Class 1
list to map (name - > student information)
Map<String, Student> map = list.stream() .collect(Collectors.toMap(Student::getName, u -> u)); map.forEach((k, v) -> System.out.println("k= " + k + ", v= " + v.toString()));
k = Li Si, v = streamtest Student (classno = class 3, name = Li Si, enName=ls, age=16, sex = male, totalScore=267)
k = Li Xiaohua, v = streamtest Student (classno = class 2, name = Li Xiaohua, enName=, age=18, sex = female, totalScore=281)
k = Zhang San, v = streamtest Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalScore=299)
k = Lin Dazhuang, v = streamtest Student (classno = class 2, name = Lin Dazhuang, enName=, age=17, sex = male, totalScore=297)
k = Liu Laoliu, v = streamtest Student (classno = class 1, name = Liu Laoliu, enName=lll, age=19, sex = male, totalScore=300)
k = Wang Xiaoming, v = streamtest Student (classno = class 1, name = Wang Xiaoming, enName=xm, age=17, sex = male, totalScore=278)
k = Zhou Dahong, v = streamtest Student (classno = class 3, name = Zhou Dahong, enName=, age=18, sex = female, totalScore=255)
k = Chen Huahua, v = streamtest Student (classno = class 4, name = Chen Huahua, enName=, age=17, sex = female, totalScore=281)
k = Wang Laowu, v = streamtest Student (classno = class 2, name = Wang Laowu, enName=wlw, age=20, sex = male, totalScore=229)
3.11.reduce()
reduce() protocol operation. You can generate a value from the Stream. The generated value is not arbitrary, but according to the specified calculation model, such as max, min, sum, etc.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); //Accumulation, two ways int sum1 = numbers.stream().reduce(0, (a, b) -> a + b); int sum2 = numbers.stream().reduce(0, Integer::sum); //subtract consecutively int sum3 = numbers.stream().reduce(0, (a, b) -> a - b); //accumulative multiplication int sum4 = numbers.stream().reduce(1, (a, b) -> a * b); //Accumulation and elimination int sum5 = numbers.stream().reduce(1, (a, b) -> a / b); //Print System.out.println("sum1: " + sum1); System.out.println("sum2: " + sum2); System.out.println("sum3: " + sum3); System.out.println("sum4: " + sum4); System.out.println("sum5: " + sum5);
sum1: 45
sum2: 45
sum3: -45
sum4: 362880
sum5: 0
3.12.Optional (Extended)
optional class is a nullable container object. If the value exists, the isPresent() method will return true, and calling the get() method will return the object. Optional is a container: it can hold values of type T or just null. Optional provides many useful methods so that we don't need to explicitly detect null values. The introduction of optional class solves the null pointer exception very well.
Common methods and descriptions
method | describe |
---|---|
empty() | Returns an empty Optional instance |
equals(Object obj) | Determine whether other objects are equal to Optiona |
get() | If this value is included in the Optional, return the value; otherwise, throw an exception: NoSuchElementException |
ifPresent(Consumer<? super T> consumer) | If the value exists, the consumer is called with that value, otherwise nothing is done |
isPresent() | If the value exists, the method will return true; otherwise, it will return false |
map(Function<? super T,? extends U> mapper) | If there is a value, call the mapping function to get the return value. If the return value is not null, an option containing the map return value is created as the return value of the map method; otherwise, an empty option is returned |
of(T value) | Returns an Optional with a specified non null value |
ofNullable(T value) | If it is not empty, the specified value of the Optional description is returned; otherwise, an empty Optional description is returned |
orElse(T other) | If the value exists, return the value; otherwise, return other |
orElseGet(Supplier<? extends T> other) | If the value exists, return the value; otherwise, trigger other and return the result of the other call |
orElseThrow(Supplier<? extends X> exceptionSupplier) | If the value exists, the contained value is returned; otherwise, an exception inherited by the Supplier is thrown |
(1) Ofnullable() or else, even if the list is empty, there will be no null pointer exception
List<Student> list = null; List<String> collect = Optional .ofNullable(list) .orElse(new ArrayList<>()).stream() .map(Student::getName) .collect(Collectors.toList()); collect.forEach(System.out::println);
(2) orElse() orElseGet() default
String value = "abc"; String nullValue = null; //If it is blank, the value is none String str1 = Optional.ofNullable(value).orElse("none"); String str2 = Optional.ofNullable(nullValue).orElse("none"); //If it is blank, the default value is set to default String str3 = Optional.ofNullable(value).orElseGet(() -> "default"); String str4 = Optional.ofNullable(nullValue).orElseGet(() -> "default"); //Print System.out.println("str1: " + str1); System.out.println("str2: " + str2); System.out.println("str3: " + str3); System.out.println("str4: " + str4);
str1: abc
str2: none
str3: abc
str4: default
(3) orElseThrow() is null throw exception
String value = null; String str = Optional.ofNullable(value).orElseThrow(IllegalArgumentException::new);
Process 'command '***/jdk1.8.0_212/bin/java.exe'' finished with non-zero exit value 1
3.13.findFirst()
Get the first element
Optional<Student> first = list.stream().findFirst(); //Print if present first.ifPresent(System.out::println);
StreamTest. Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalScore=299)
3.14.findAny()
Returns any element
Optional<Student> first = list.stream().findAny(); //Print if present first.ifPresent(System.out::println);
StreamTest. Student (classno = class 1, name = Zhang San, enName=zs, age=18, sex = male, totalScore=299)
3.15.peek()
as can be seen from the above, pee() is a stateless intermediate operation, while the flow has a life cycle. The life cycle of the flow is divided into three stages: initial stage, intermediate operation (inert, no operation will affect the flow before it flows in the pipeline) Termination operations (usually divided into two types: final consumption such as foreach and induction such as collect. The terminal operation starts the flow of the flow in the pipeline). Therefore, after peek(), it needs to be followed by a terminal operation to see the effect.
Since peek() is not followed by any termination operation, the following code will not print anything
Stream<String> stream = Stream.of("abc", "def"); stream.peek(System.out::println);
Connect a termination operation to see the print
Stream<String> stream = Stream.of("abc", "def"); List<String> strs = stream.peek(System.out::println).collect(Collectors.toList());
abc
def
It is often used to debug. For the following convection filtering, it is required to take out the qualified elements with a length greater than 3 and turn the elements into uppercase (the values of this process, i.e. the original value and the converted value, can be clearly debugged and printed through peek() twice)
Stream.of("one", "two", "three", "four").filter(s -> s.length() > 3) .peek(s -> System.out.println("Original value: " + s)) .map(String::toUpperCase) .peek(s -> System.out.println("Conversion value: " + s)) .collect(Collectors.toList());
Original value: three
Conversion value: THREE
Original value: four
Conversion value: FOUR
3.16.flatMap()
flatMap() is an intermediate operation, also known as flow flattening. Like map(), flatMap() is an intermediate operation of collection type, but different from map, it can split (slice) a single element in the flow.
(1) Case 1: re splitting the word elements in the array
List<String> wordList = Arrays.asList("Hello", "World"); List<String> letterList = wordList.stream() .map(word -> word.split("")) .flatMap(Arrays::stream) .distinct()//This step is to de duplicate the words, but not the key .collect(Collectors.toList()); letterList.forEach(s -> System.out.print(s + ","));
H,e,l,o,W,r,d,
(2) In case 2, the element set in the set is split again
// List of classes (data) List<String> class1 = Arrays.asList("class1-ab", "class1-bc", "class1-df"); List<String> class2 = Arrays.asList("class2-ab", "class2-bc", "class2-df"); List<String> class3 = Arrays.asList("class3-ab", "class3-bc", "class3-df"); // Total list of annual segments (data) List<List<String>> allClass = Arrays.asList(class1, class2, class3); List<String> flatMapList = allClass.stream() .flatMap(Collection::stream) //Writing method 2 flatmap (s - > s.stream()) .collect(Collectors.toList()); flatMapList.forEach(s -> System.out.print(s + ", "));
class1-ab, class1-bc, class1-df, class2-ab, class2-bc, class2-df, class3-ab, class3-bc, class3-df,