Streams

You can consider steam as a wrapper that wraps the collection object and allows you to operate on it and makes the bulk process easy and fast.

Does it have any potentials to modify the data?

To answer this question, A stream is not a data structure to hold the data, and hence it is not libel to modify the data structure.

Why collection often compared with Streams?

Let’s see first what is collection then will see if it is really worth to be compared against collection.

What is collection?

When someone normally says collection the here they are referring to the concept. And when someone programmatically says Collection i.e with C in the upper case then we should infer with that as they are referring to an interface in the collection framework concept.
Collections, on the other hand, refer to the class in the collection framework concept

Collection VS Collections

To remember this let’s remember a hack (Note: This is just a small tip to not confuse between Collection and Collections )Collections(S) when you see (s) its a class since class ends with s so id collections. whereas Collection is an interface.

When to use the collection?
The collection is basically used when you what to store the state of the processed or unprocessed objects.

When to use stream?

Streams are basically used when we want to process objects and do not want to store its state, then we can go ahead and use java streams. It is available in java.util* package. its an interface.
So I guess the above-provided information is enough to distinguish between both stream and collection.
Before even diving deeper let try to know where all can we use this stream and for what purpose.
NOTE: Stream was basically designed to work with LAMBDAS expression. So you should try using java 8 and above for learning this concept.
To operate on any of the collections to do operations like a filter, map, etc. We need to get the stream object for the collection. To do so we need to do something like,
Stream <stream_obj_ref_name> = <colletion>.stream();
So we can observe that we need a Stream() method to get the stream object.

Now the first question that arises is there a way to create stream without using this stream() method?
So the answer is yes, it can be done using the Stream.of() method will be something like this.

Stream streamObject= Stream.of(“aaa”, ”bbb”, ”ccc”);
Maybe with type safety, we can write something like this.
Stream<String> streamObject= Stream.of(“aaa”,”bbb”,”ccc”);
Stream<Integer> streamIntegerObject= Stream.of(1,2,3,4,5);
Stream<Integer> streamIntegerObject= Stream.of(new Intger[]{1,2,3,4,5});

Now my next question is, What all we do with the stream, and what all methods are available here to ease our data processing job?
Intermediate Operations
  • filter
  • map
  • flatMap
  • distinct
  • sorted
  • limit
  • skip

Terminal Operations

  • forEach
  • toArray
  • reduce
  • collect
  • max
  • min
  • count
  • anyMatch
  • allMatch
  • nonMatch
  • findFirtst
  • findAny

Stream MapThe map  operation converts each element into another object .

nameList.stream().filter((s) -> s.startsWith(“K”)).map(String::toUpperCase)                    

So in this case what we are doing is we are converting it from lowercase to upper case .This can also be used to convert it to some other custom type Object. Below is the syntax  which is internally acting upon it.

<R> Stream<R> map(Function<? super T, ? extends R> mapper);
So once you see this Function 
@FunctionalInterfacepublic interface Function<T, R> {
    /*** Applies this function to the given argument.     *    
* @param t the function argument     
* @return the function result   
   */   
R apply(T t); }

Ex:  To make it more clear let see how to do it without lambda expression,let name of the stream list be nameListnameList
nameListnameList.stream().filter(p->{}).map(new Function<T,R>(){
@overridepublic 
Object apply(){
// now inside it  the actual conversion will happen.
}})
Lest take a custom class example to see how the map works to convert from one object to another.

Basic needs:

  1. create a custom MyCompany class
  2. create a steam of strings.
  3. Iterate the stream
  4. and then use the map to convert to MyCompany Object
package com.in.stream.eg;
import java.util.ArrayList; 
import java.util.List; 
import java.util.function.Function; 
import java.util.stream.Stream;

public class StreamTest {
public void demonstrateMapMehod() {
List<String> nameList = new ArrayList<String>(); nameList.add("Theorems");
nameList.add("trubee");
Stream<String> nameStream = nameList.stream();

nameStream.map ( new Function<String, MyCompany>() { 
@Override
public MyCompany apply(String companyName) {
 MyCompany myCompany = new MyCompany(companyName); 
   return myCompany;
}
}).forEach((p) -> System.out.println(p));
}

public String printExistinglList() { 
List<String> nameList = new ArrayList<String>(); nameList.add("Theorems");
nameList.add("trubee");
Stream<String> nameStream = nameList.stream(); 
nameStream.forEach(p -> System.out.println(p)); 
return null; 
}
public static void main(String[] args) { 
StreamTest streamTest = new StreamTest(); 
streamTest.printExistinglList();
streamTest.demonstrateMapMehod();
streamTest.convertToupperCase();
}

public void convertToupperCase() {
List<String> nameList = new ArrayList<String>();
nameList.add("Theorems");
nameList.add("trubee");
nameList.stream()
    .map(String::toUpperCase)
    .forEach(System.out::println);
}
}
O/P
Theorems
trubee
[email protected]
[email protected]
THEOREMS
TRUBEE
class MyCompany { 
String companyName;
MyCompany(String companyName) { 
this.companyName = companyName; 
}
}
O/P
[email protected]
[email protected]
THEOREMS
TRUBEE

Stream.sorted()

Sorted operation that returns a sorted view of the stream.

public class StreamSort {
public static void main(String[] args) {
List<String> list = Arrays.asList("dd", "aa", "kk", "bb");
System.out.println("The sorted stream is : ");
list.stream().sorted().forEach(System.out::println);
}
}

What is the terminal operation in a stream?

Terminal operation in Steams basically returns the result of a certain type but not stream type.Stream forEach().It basically works as for loop just an enhanced form of a loop. Which can be used used to iterate over the elements.

public class ItreateList{
public static void main(String as[]){
List<Integer> list= new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Stream listStream= list.stream();
listStream.forEach(p->System.out.println(p));
}
}

Stream.collect();

It basically collect the data in different collection type like as list , asSet, asMap, etc.

public class ItreateList {
public static void main(String as[]) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Stream listStream = list.stream();
listStream.sorted().collect(Collectors.toList());
}
}
public class ItreateList {
public static void main(String as[]) {
List<String> list = new ArrayList<String>();
list.add("aa");
list.add("zz");
list.add("gg");
list.add("cc");
List<String> newList = null;
list.stream().sorted().forEach(p -> System.out.print(p));
// Now using collectors:
newList = list.stream().sorted().collect(Collectors.toList());
System.out.println(newList);
}
}

Stream.match()
This function returns an output as boolean if the match is obtained for anyMatch.

public class ItreateList {
public static void main(Stringas[]) {
List<String>list=newArrayList<String>();
list.add("aa");
list.add("zz");
list.add("gg");
list.add("cc");
booleanmatchedResult=list.stream().anyMatch((s) ->s.startsWith("A"));
System.out.println(matchedResult);
}
}
100% LikesVS
0% Dislikes

Leave a Reply

Your email address will not be published. Required fields are marked *