How to resolve the sun.security.validator.ValidatorException: PKIX path building failed



When you first setup Maven in your office/home computer you might come up with an exception as below when you try to run/build the Maven project.


Could not transfer artifact com.adobe.aem:aem-api:pom:6.0.0.1 from/to adobe-public-releases (https://repo.adobe.com/nexus/content/groups/public): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target -> [Help 1]

SOLUTION to sun.security.validator.ValidatorException: PKIX path building failed

So for the exception above we can see that the URL is clearly mentioned in the exception report. In this case it is https://repo.adobe.com/nexus/content/groups/public


Resolution Steps:


STEP 1:  Navigate to the URL in the exception report using a browser. In this case I am using Google Chrome browser. See below snapshot.



STEP 2: Now press F12 or right click on the page and click on “Inspect”. This will open the developer tools.


STEP 3: Go to the “Security” tab.

STEP 4: Click on the “View Certificate” button.


STEP 5: Check the name of the Certificate (or the issuing authority)



STEP 6: Now close this window and go to browser “Settings”.


STEP 7: Now search for “Manage Certificates”. Alternatively, you can open the “Internet Options” in IE or similar browser and go to “Content” tab and click on “Certificates” button.




STEP 8: Now find the name of the certificate matching the one in STEP 5.




STEP 9: Click on “Export” and export it in a new file (using the default selected format).



STEP 10: Now run the JAVA  Keytool command to add this certificate to your computer’s JDK keystore.


STEP 11: You should run this command.

keytool -import -alias ctsrootca3 -file D:\certs\ctsrootca3.cer -keystore "C:\Program Files\Java\jdk1.8.0_152\jre\lib\security\cacerts"

Please make changes as below.
D:\certs\ctsrootca3.cer  - This should be the path to your certificate file that you exported.
C:\Program Files\Java\jdk1.8.0_152 – This should be path to your JDK folder.
 
If prompted for a password use : “changeit” (without the quotes, this is the default password for cacerts file)



STEP 12: After successful addition of the key you will see a message like this.



STEP 13: If you have followed this steps correctly then now when you run Maven it should not give any errors.



How to resolve ObjectFactory Collisions in JAVA

In my previous article I have explained how to generate the web service classes.If you have not already read the topic then I would advise you to do so. Moving on, we can sometimes get an error like below

[ERROR] Two declarations cause a collision in the ObjectFactory cl
  line 1191 of file:/D:/RAMEEZ/Web%20Services/TeamBpl/TeamBpl3.xsd

[ERROR] (Related to above error) This is the other declaration.
  line 981 of file:/D:/RAMEEZ/Web%20Services/TeamBpl/TeamBpl3.xsd

This is a very common issue we face, and the way to resolve this is to simply write a XML file having a JAXB binding configuration.

Simple Steps for Clear Understanding:

Here are a few simple steps with images to help you fix the issue quickly :)


STEP 1:

Analyze the issue.
From the above error log we see line number 1191 and 981 have issues in the
XSD Schema file. Lets look into the XSD file. See below.



STEP 2:

So this is happening because the "name" attribute is somehow causing collision when the WSDL file is getting parsed.


STEP 3:

To solve this simple open a new file in Notepad(or any text editor you use) and name it something like "conflict.xml".

STEP 4:

Copy it from here.

<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 <jxb:bindings node="/xs:schema" schemalocation="TeamBpl3.xsd">
  <jxb:bindings schemalocation="TeamBpl3.xsd">
   <jxb:bindings node="./xs:element[@name='MediaUrl']">
    <jxb:factorymethod name="RootMediaElement">
   </jxb:factorymethod></jxb:bindings>
  </jxb:bindings>
 </jxb:bindings> 


</jxb:bindings> 



STEP 5:

Now run the "wsimport" command with the -b switch. This is called the binding (-b).

wsimport [WSDL_FILE.wsdl] -b conflict.xml -keep -verbose

STEP 6:

This will generate the stub classes properly without any issues.




REMEMBER:

When you have multiple collisions then in that case you have to write multiple jxb:bindings for each. Means you have to repeat line number 5 to 11 from STEP 3.

Hope this helps!



Steps to Create Web Service Stub

This document gives instructions on creating web service stubs better knowas proxy classes. We will take an example and proceed with the explanation.

STEP 1:

Copy the URL link in the browser address bar and hit enter.Check if the WSDL is accessible through your network or not.

STEP 2:

Download the WSDL file in a folder and should be saved with the ".wsdl" extension.

STEP 3:

Now start to download the artifacts in a folder in your local drive.This should include the WSDL file and all the associated XSDs. The XSD files can be downloaded from the links found inside the downloaded WSDL file.

STEP 4:

Go into the WSDL file.You will see a section having the schemas.

STEP 5:

Rename the XSD Http links.Point it to the local path of the XML Schemas.

STEP 6:

Open a command prompt and check the "wsimport" tool.

STEP 7:

We will use the wsimport and the associated commands to create the stubs.Please check the snap shot below f the command prompt.The command is like:wsimport -keep -extensionThere are many associated commands. We need to use them as and when required.

STEP 8:

After the previous command we can see folders created in the same destination of the artifact files.

STEP 9:

Copy this folders in the “src” folder of your JAVA project in your IDE.It should look like this ad you are good to go.

 

Java DecimalFormat - For Large Decimal Point Numbers

The Java DecimalFormat class helps us to format numbers in many ways. I was trying to convert
a big number to a 2 decimal point number.Thought of sharing the same with some explaination.

Trying to achieve this:    1,308,207 ---> 1.31


    String number = "1,308,207";
    java.text.DecimalFormat df = new java.text.DecimalFormat("#.##");
    number = number.replace(",", ""); 
    Float f = Float.parseFloat(number) / 1000000;
    String result = df.format(f); 
    System.out.println(result);   // result = 1.31

So how does it work??

Well it works like this. DecimalFromat uses java.math.RoundingMode.HALF_EVEN method which
rounds off the number to nearest even i.e when it's 0.05 it becomes 0.1.

1. The number becomes 1308207 at line 3.
2. At line no. 5 it becomes 1.308207.
3. Now the actual formatting starts:-
4. The right hand side(RHS) value is 07,so nearest round off is 10, only 1 taken & RHS discarded.
5. Now the number becomes 1.308201
6. Rightmost 01,the nearest round off id 00, RHS discarded & number becomes 0.
7. Again number becomes smaller 1.30820, in same way becomes 1.3082.
8. Next step : 1.308
9. Finally 1.31(08 becomes 10 with HALF_EVEN method and 0 discarded).


Do you have suggestions or want to improve the solution? Please do feel free to write back to us

List of deprecated Java packages in AEM 6.2


Here is a list of deprecated packages in AEM 6.2 that you should keep handy for your reference.
If you are not sure the new package/API you just Googled out is deprecated or not, then just
do a quick search here.

If it is there in the list , it shouldn't be there in your code!!



com.adobe.aem.formsndocuments.listeners
com.adobe.cq.creativecloud.cloudims
com.adobe.cq.creativecloud.filesync
com.adobe.cq.creativecloud.home
com.adobe.cq.dms.tagmanager
com.adobe.cq.mcm.silverpop
com.adobe.cq.social.blog
com.adobe.cq.social.blog.antispam
com.adobe.cq.social.blog.antispam.process
com.adobe.cq.social.blog.search
com.adobe.cq.social.blog.search.process
com.adobe.cq.social.blog.trackback
com.adobe.cq.social.blueprint.endpoints
com.adobe.cq.social.sc.lucene
com.adobe.cq.social.scoring.util
com.adobe.granite.ocs.api
com.adobe.granite.ocs.api.goals
com.adobe.granite.ocs.api.provider
com.adobe.livecycle.formsmanagement.api
com.adobe.livecycle.formsmanagement.exception
com.day.cq.activitystreams.api
com.day.cq.auth.pin
com.day.cq.dam.html
com.day.cq.jobs.core
com.day.cq.searchpromote.feed
com.day.cq.searchpromote.feed.api
com.day.crx.sc.api
com.day.crx.sc.osgi
com.day.crx.sc.qom
org.apache.aries.subsystem
org.apache.commons.imaging.formats.bmp.pixelparsers
org.apache.commons.imaging.formats.bmp.writers
org.apache.commons.imaging.formats.tga
org.apache.felix.prefs
org.apache.felix.scr
org.apache.jackrabbit.mk.api
org.apache.jackrabbit.oak.commons.mk
org.apache.jackrabbit.oak.kernel
org.apache.jackrabbit.oak.security.authentication.ldap
org.apache.sling.event
org.apache.sling.jcr.compiler
org.eclipse.equinox.region
org.joda.time.tz.data
org.joda.time.tz.data.Africa
org.joda.time.tz.data.America
org.joda.time.tz.data.America.Argentina
org.joda.time.tz.data.America.Indiana
org.joda.time.tz.data.America.Kentucky
org.joda.time.tz.data.America.North_Dakota
org.joda.time.tz.data.Antarctica
org.joda.time.tz.data.Asia
org.joda.time.tz.data.Atlantic
org.joda.time.tz.data.Australia
org.joda.time.tz.data.Etc
org.joda.time.tz.data.Europe
org.joda.time.tz.data.Indian
org.joda.time.tz.data.Pacific
org.osgi.service.prefs
org.osgi.service.repository
org.osgi.service.subsystem

Let me know about any issues. Suggestions are always welcome....


A solution for javax.jcr.lock.LockException

In one of my previous posts I showed how to connect to JCR using a simple
main() method , Java program
.
This is a simple program and should work fine in most of the cases.
But for some people it might throw a javax.jcr.lock.LockException.

Solution:

While connecting to the JCR we may use something like below.

 Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
This statement may sometimes lead to an error in applications like AEM.
To avoid this we need to mention the default environemnt we are logging into.

So we should USE THIS INSTEAD.

Session session = repository.login( new SimpleCredentials("admin", "admin".toCharArray()),"crx.default");



I would be happy to hear back from you. Please leave your suggestions in the comment section below. Cheers!!



[FIX]:  javax.inject,version=[0.0,1) -- Cannot be resolved

The Scene:

So on a Saturday afernoon I was working on some AEM backend services and I came
across this issue which I have never faced before. It was something to do with the
javax.inject package that is used when we are using the @Inject annotations
in our classes.

The Problem:

So like a normal developer bloke I Googled around a bit and came to know that this was some
kind of dependency issue. But I was surprised that even though we can find the dependency using
depfinder --> http://localhost:4502/system/console/depfinder it was not resolved.


Finally the SOLUTION:

So I tried adding the javax.inject dependencies to my project POM file (i was using Maven)
and it WORKED!!!

    <dependency>
        <groupId>org.apache.geronimo.specs</groupId>
        <artifactId>geronimo-atinject_1.0_spec</artifactId>
        <version>1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>


The Cause:

Though I am not quite sure about the cause for this issue but I believe
this is a problem persistent in AEM version 6.2 (AEM 6.2 javax.inject dependency problem)
as I have executed the same code in AEM 6.1 without issues.

Please let me know in the comments below if you have the reason or additional info.

Remove SOAP Request XML parameter programmatically.

SOAP is a protocol that allows systems to communicate using HTTP and uses predominantly XML
for communication. The necessity of web applications to inter communicate made it necessary for
a protocol to be designed.

Sometimes when setting the web service parameters there are compulsory parameters whose values needs
to be set. But passing these parameter might cause the Web Service to fail. So a situation may arise
where we need to both set the web service parameter value as well as remove the parameter from the
request XML!!!

So lets say for example you have a webservice parameter like this:

<ProductName>CoderMagnet<ProductName>
<CodeValue>...</CodeValue>
<ProductId>ABCXYZ<ProductId>


Suppose passing this value in the request xml is giving an error.
And also lets assume this is being set from the JAVA program like this.


product.setProductName("CoderMagnet");
product.setCodeValue("ABC123");
product.setProductId("004");



Now to remove this parameter from the web service request XML we just need to set
the parameter as NULL. This will remove the web service parameter from the request XML.


product.setProductName("CoderMagnet");
product.setCodeValue(null);
product.setProductId("004");



Afer you set a web service parameter to null. It will automatically
be dropped like shown below.


<ProductName>CoderMagnet<ProductName>
<ProductId>004<ProductId>



We can see from the above XML that the CodeValue got dropped.




How to iterate over a HashMap in Java

Iterating over a HashMap in Java is a very common task but can be tricky sometimes
since it uses the Entry object (java.util.Map.Entry) which we may not be familiar with readily.

Whenever we need to "Iterate over a HashMap" we need to call the entrySet() method over the map
object and then only we can iterate over it.


This is best achieved in the following two ways.
Supposing we have a Hashmap like like this.


Map<String,String> timeZones=new HashMap<String, String>();
 
timeZones.put(" (GMT-12:00) ", " International Date Line West ");
timeZones.put(" (GMT-11:00) ", " Midway Island ");
timeZones.put(" (GMT-10:00) ", " Hawaii Time ");
timeZones.put(" (GMT-09:00) ", " Alaska Time ");
timeZones.put(" (GMT-08:00) ", " Pacific Time (US and Canada) ");


Method 1: Using For Each Loop to iterate over a HashMap

for(Map.Entry timeZone : timeZones.entrySet()){

    System.out.println(timeZone.getKey() + " is the " + timeZone.getValue());

  }


Method 2: Using Iterator and While Loop to iterate over a HashMap

 while (it.hasNext()) {
  
  Entry timeZone = (Entry)it.next();
  System.out.println(timeZone.getKey() + " is the " + timeZone.getValue());
  it.remove(); 
    }


Output:

 (GMT-08:00)  is the  Pacific Time (US and Canada) 
 (GMT-12:00)  is the  International Date Line West 
 (GMT-09:00)  is the  Alaska Time 
 (GMT-10:00)  is the  Hawaii Time 
 (GMT-11:00)  is the  Midway Island


Well in both cases the result is he same. Its depends on the taste and the situation
to decide which one of the method you want to use.
Going a little deeper we can look into other requirements of HashMap iteration.





Iterate over a HashMap Values/ How to iterate over the values in a HashMap.

Well you may very well come across a situation where you only need to iterate over HashMap values.
This can be easily achieved in the following two ways.

 for(String timeZone : timeZones.values()){

  System.out.println(timeZone);
 }


OR,


Iterator it = timeZones.values().iterator();

 while (it.hasNext()) {
  String timeZone = (String) it.next();
  System.out.println(timeZone);
  it.remove();
 }


Output:

 Pacific Time (US and Canada) 
 International Date Line West 
 Alaska Time 
 Hawaii Time 
 Midway Island 






Iterate over a HashMap Keys/ How to iterate over the Keys in a HashMap.

You may also need to iterate over HashMap keys. This HashMap iteration is shown below.

 for (String timeZone : timeZones.keySet()) {

  System.out.println(timeZone);
 }


OR,


Iterator it = timeZones.keySet().iterator();

 while (it.hasNext()) {
  String timeZone = (String) it.next();
  System.out.println(timeZone);
  it.remove();
 }


Output:

 (GMT-08:00) 
 (GMT-12:00) 
 (GMT-09:00) 
 (GMT-10:00) 
 (GMT-11:00) 


System Bundles going to Installed State | AEM Bundles not Starting

Many a times while working with AEM we find various errors related to bundles.Bundles or JAR files forms the backbone of AEM. When these bundles goes o installed state they give rise to
issues like 403 forbidden errors, 500 internal server errors or sometimes errorsrelated and not
limited to ACS Commons or DAM.


Sometimes it is very dificult to find as to why AEM bundles are going to installed state.
The reason being that various operations can cause your bundles to go to installed state.


Adobe has given us a HOTFIX for this issue.
"AEM bundles going to installed sate" HOTFIX comes in the form of a small JAR file.
he AEM bundle hotfix comes in the form of org.eclipse.equinox.region jar file.

Ok enough TALKING... Gimme the SOLUTION Please..!!!!

Solution 1:

If you have tried other ways and just couldn't get it working and still see various AEM system
bundles in installed state then try to install this JAR into your Felix console /system/console/bundles.


JAR Download : https://drive.google.com/open?id=0B3gwHkSOERmZRlZNQzZUMEFoUzQ

This is a good fix which works most of the time. Also trying this solution will not hurt.You can
always delete the bundle if it didn't do the job.

NOTE:
AEM will refresh all the bundles. So please wait 5 minutes after installing the Equinox HOTFIX.


Solution 2:

For AEM version 6.1 only.

If the above method didn't resolve your problem then try to remove equinox related JAR file.
Look for a bundle with this name "Region Digraph(org.eclipse.equinox.region)"

Now remove this bundle. Also remove the bundle you installed in Solution 1 if necessary.
Long story short, there should not be any equinox jars installed.



Why this Happens?

According to Adobe the equinox eclipse bundle has some dependency with eclipse and should not be in AEM6.1, it was meant for AEM version 6.2. But this bundle got introduced in this version.

Other Version of Jar file:
1. http://www.java2s.com/Code/Jar/o/Downloadorgeclipseequinoxregion110v201205221841jar.htm



How to convert String to Int in Java

Converting a String to Int in Java is a common scenario which we face everyday.
Now this can be achieved in multiple ways.

Integer.parseInt()
Integer.parseInt() returns a primitive int datatype.

String num = "12345";
int number = 0;

try {  
number = Integer.parseInt(num);   
} 
catch (NumberFormatException e) {
}


Integer.valueOf()
The Integer.valueOf() method returns an cached instance of java.lang.Integer.

String num = "12345";
Integer number = 0;
try {
      number = Integer.valueOf(num);
    } 
catch (NumberFormatException e) {
}


Integer.decode()
This basically decodes a String into an Integer.It returns a wrapper object of type java.lang.Integer.
It accepts Strings in the formats like DecimalNumeral, HexDigits, and OctalDigits.
DecimalNumeral, HexDigits, and OctalDigits are as defined in section 3.10.1 of The Java™ Language
Specification, except that underscores are not accepted between digits.

String num = "12345";
Integer number = 0;
try {
      number = Integer.decode(num);
    } 
catch (NumberFormatException e) {
}


Integer.decode() for Octal numbers

String num = "022";
Integer number = 0;
try {
      number = Integer.decode(num); //18
    } 
catch (NumberFormatException e) {
}


Integer.decode() for Hexadecimal numbers

String num = "0X12A";
Integer number = 0;
try {
      number = Integer.decode(num); //298
    } 
catch (NumberFormatException e) {
}


Retrieve List from java.util.Stream in Java 8

In the previous article I explained the new class introduced in Java 8 called Optional.
Today I was working with streams and needed to convert it to a List. So thought of sharing this..

Go here if you need to Convert a List to Stream.
Stream API in Java 8 does not define a direct operation or standard to convert a stream data,
into a List. Java 8 design pattern unfortunately does not allow direct conversions from the Stream
to Collections like List or Set.

However not everything is lost, as the developers have given us the
concept of Collectors.You can read more about collectors in my Simple Collector Tutorial.
Using Collectors we can easily achieve inter conversions from Stream to Collections.


There are various method explaining how to convert Stream to List in Java 8.
Here are the most common ones.

The Collectors.toList() method


The Collectors.toList() method is the most straightforward method to convert Stream to List in java 8.
It involves some simple code.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=streamData.collect(Collectors.toList());

System.out.println(newList);  //[Convert, Stream, to, List]

Most of the daily requirements will be addressed by the above method
but if in case you are the odd one out who just can't do thing as the normal
people do, then you might look at the below options as well.



The Collectors.toCollection() method to convert a Stream to List in Java8


This is quite same as the previous one except for the fact that it is more generalized
conversion. The toCollection() can be used to convert Stream to other collection class also
like for example a TreeSet.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=streamData.collect(Collectors.toCollection(ArrayList::new ));
//TreeSet<String> set=streamData.collect(Collectors.toCollection(TreeSet::new ));

System.out.println(newList);  //[Convert, Stream, to, List]



Using forEach() to convert a Stream to List in Java 8


Ok so this is a crude way of converting a Stream to a List. But if the other options
are not good enough for you then you might try out this one. Here what we will traverse
through the elements of the Stream using the forEach() loop and add each element to the List.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=new ArrayList<String>();
 
streamData.forEach(newList::add);
 
System.out.println(newList);  // [Convert, Stream, to, List]



Using forEachOrdered() to convert a Stream to ordered List in Java 8


The forEach() will work with Streams pretty good. But there is a catch.
In case of parallel streams where multiple Stream data is processed horizontally
it will break the ordering. So you will end up with a jumbled list of objects from the initial
Stream. The forEachOrdered() helps to traverse a parallel stream in an orderly way. So the
list you will get will maintain the initial order of elements as present in the parent Stream.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=new ArrayList<String>();
 
streamData.forEachOrdered(newList::add);
 
System.out.println(newList);  // [Convert, Stream, to, List]




Using toArray() and Arrays.asList() to convert a Stream to List in Java 8


If you are really looking to lower efficiency, readability and clarity of our code
and you do not like the normal stuff that others do then you can try this out.
Jokes apart, this method can be used to learn the features of Stream and also to
understand the basics of Streams and Collections in Java 8.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=(List<String>)(Object)Arrays.asList(streamData.toArray());

System.out.println(newList);  // [Convert, Stream, to, List]



Conclusion:

To conclude we can adopt various steps to convert Stream to List in Java 8.
Since there is no direct way to do this I leave it upto you to choose the best method
for your development activity.However I prefer the first two methods using Collectors.

SEE ALSO: Convert a List to Stream in Java 8.


Convert List<V> into Map<K, V> in Java 8

Sometimes it is necessary to convert a List of Objects to Map in Java 8.
In Java 8 we can simply do this using Collectors class .
Let us look at the following example.


class Employee {
 public String name;
 public int age;

 Employee(String name, int age) {
  this.name = name;
  this.age = age;
 }

 public String getName() {
  return name;
 }

Now we can convert a list of Employee Objects to a Map like this
We will use the names of the Employees as the key of the Map.


List<Employee> empList = Arrays.asList(
                            new Employee("Jim", 18),
                            new Employee("Joe", 25), 
                            new Employee("Harry", 40)
                            );
  
Map<String, Employee> result = empList.stream()
                    .collect(Collectors.toMap(Employee::getName, x -> x));

System.out.println(result);


Output:

{
Joe   = codermag.net.java8.Employee@404b9385, 
Harry = codermag.net.java8.Employee@6d311334, 
Jim   = codermag.net.java8.Employee@682a0b20
}

When to use Java 8 forEach() over Enhanced For loop

Well in Java 8 you have an option to call the forEach() method over any iterable.
This is simply iterable.forEach(action), where forEach() performs the given action for
each element of the Iterable until all elements have been processed or the action throws an exception.

In normal scenarios there is absolutely no noticeable difference in performance.
So an operation like 1 and 2 this will yield similar results.


List<String> items = Arrays.asList("Hello", "Java", "Developer","CoderMagnet");


Operation 1:
items.forEach(System.out::println);
Operation 2:

for (String item : items) 
{
   System.out.println(item);
}
Output (Same for Both)

Hello
Java
Developer
CoderMagnet



So where is the difference????

The main advantage of forEach() is observed when it is invoked over a Java8 parallel stream.Parallel
execution reduces processing time. But unlike the previous example the sequential order is not maintained.
Long story short, forEach() over parallel streams will execute much faster.



// Normal Stream (Slower, sequential order maintained)
items.stream().forEach(System.out :: print);

System.out.println("\n");

// Parallel Stream (Executes much faster, sequential order not maintained)
items.parallelStream().forEach(System.out :: print);
Output:

Hello Java Developer CoderMagnet 

Developer CoderMagnet Java Hello 


The Java8 forEach() should be used to boost performance in situations where parallel executions
can boost performance. But we should remember that parallel execution will not maintain the
sequential nature of data iteration.

How to convert a List<Object> to List

This is a tricky situation that you may end up with sometimes.
Directly typecasting like shown below doesn't work:

List<String> stringList=(List<String>)objList;


Typecasting List<Object> to List<String> but it does not work as typecasting generic types is
not allowed. So this can be achieved by converting a List<Object> to an intermediate.
We can acheive this conversion in the following ways.


Typecasting the List itself as a simple Object and then to its generic type.

List<Object> objList=Arrays.asList("Hello", "World","CoderMagnet");
List<String> stringList=(List<String>)(Object)objList;


You can typecast through an intermediate wildcard.

List<Object> objList=Arrays.asList("Hello", "World","CoderMagnet");
List<String> stringList=(List<String>)(List<?>)objList;




Convert a java.util.List to java.util.Stream in Java 8

In my previous example I showed "How to convert Stream into a List in Java 8".
In this example I will show how to convert a List into a Stream in Java 8.

Collections like the List can be easily obtained from a Java 8 Stream
by calling the stream() operation over a List.
This is a inbuilt feature and it helps in easy conversions from collections to Stream data.

List<String> itemList=Arrays.asList("List","to","Stream","Java8","Stream");

//Converting List to Stream in Java 8
Stream<String> itemStream=itemList.stream();

itemStream.distinct().forEach(x -> System.out.print(x+" "));


SEE ALSO: How to convert Stream into a List in Java 8

Convert Stream to List in Java8

In the previous article I explained the new class introduced in Java 8 called Optional.
Today I was working with streams and needed to convert it to a List. So thought of sharing this..

Go here if you need to Convert a List to Stream.
Stream API in Java 8 does not define a direct operation or standard to convert a stream data,
into a List. Java 8 design pattern unfortunately does not allow direct conversions from the Stream
to Collections like List or Set.

However not everything is lost, as the developers have given us the
concept of Collectors.You can read more about collectors in my Simple Collector Tutorial.
Using Collectors we can easily achieve inter conversions from Stream to Collections.


There are various method explaining how to convert Stream to List in Java 8.
Here are the most common ones.

The Collectors.toList() method


The Collectors.toList() method is the most straightforward method to convert Stream to List in java 8.
It involves some simple code.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=streamData.collect(Collectors.toList());

System.out.println(newList);  //[Convert, Stream, to, List]

Most of the daily requirements will be addressed by the above method
but if in case you are the odd one out who just can't do thing as the normal
people do, then you might look at the below options as well.



The Collectors.toCollection() method to convert a Stream to List in Java8


This is quite same as the previous one except for the fact that it is more generalized
conversion. The toCollection() can be used to convert Stream to other collection class also
like for example a TreeSet.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=streamData.collect(Collectors.toCollection(ArrayList::new ));
//TreeSet<String> set=streamData.collect(Collectors.toCollection(TreeSet::new ));

System.out.println(newList);  //[Convert, Stream, to, List]



Using forEach() to convert a Stream to List in Java 8


Ok so this is a crude way of converting a Stream to a List. But if the other options
are not good enough for you then you might try out this one. Here what we will traverse
through the elements of the Stream using the forEach() loop and add each element to the List.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=new ArrayList<String>();
 
streamData.forEach(newList::add);
 
System.out.println(newList);  // [Convert, Stream, to, List]



Using forEachOrdered() to convert a Stream to ordered List in Java 8


The forEach() will work with Streams pretty good. But there is a catch.
In case of parallel streams where multiple Stream data is processed horizontally
it will break the ordering. So you will end up with a jumbled list of objects from the initial
Stream. The forEachOrdered() helps to traverse a parallel stream in an orderly way. So the
list you will get will maintain the initial order of elements as present in the parent Stream.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=new ArrayList<String>();
 
streamData.forEachOrdered(newList::add);
 
System.out.println(newList);  // [Convert, Stream, to, List]




Using toArray() and Arrays.asList() to convert a Stream to List in Java 8


If you are really looking to lower efficiency, readability and clarity of our code
and you do not like the normal stuff that others do then you can try this out.
Jokes apart, this method can be used to learn the features of Stream and also to
understand the basics of Streams and Collections in Java 8.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=(List<String>)(Object)Arrays.asList(streamData.toArray());

System.out.println(newList);  // [Convert, Stream, to, List]



Conclusion:

To conclude we can adopt various steps to convert Stream to List in Java 8.
Since there is no direct way to do this I leave it upto you to choose the best method
for your development activity.However I prefer the first two methods using Collectors.

SEE ALSO: Convert a List to Stream in Java 8.


findFirst() example in Stream, Java 8

The findFirst() operation returns an object of type Optional (tutorial for Optional Class here) describing the
first element of this stream, or an empty Optional if the stream is empty.
If the stream has no encounter order,then any element may be returned.


Stream<String> items=Stream.of("findFirst","Example","Stream","Java8");
Optional<String> op = items.findFirst();
  
System.out.println(op);       // Optional[findFirst]
System.out.println(op.get()); // findFirst


In the case where the Stream is empty the findFirst() method returns a empty Optional object.

Stream<String> items=Stream.of();
Optional<String> op = items.findFirst();

System.out.println(op); // Optional.empty


To conclude use the findFirst() method in Java 8 to find the first element of any Java 8 Stream.
It returns a object of type Optional.
If the Stream is empty it will return an empty Optional object in the form Optional.empty.



In the previous article I explained about Collectors in Java 8. Now we will move on to another class that is introduced in Java 8 called Optional.

Optional is a new class introduced in Java 8 to address problems associated with NullPointerExceptions.
The Optional object in Java 8 is used to hold a SINGLE value which as the name suggests, is optional, meaning it
has two options, that is it can be null or not-null.
Which means that it is a container object which may or may not contain a NULL value.


Some of them are Explained in details below:
Optional.isPresent()
Optional.get()
Optional.orElse()
Optional.orElseGet()
Optional.orElseThrow()
Optional.filter()
Optional.of()
Optional.ofNullable()
Optional.empty()


Consider the code sample.
We have two separate streams. Stream1 is having valid data while Stream2 is empty stream.

Stream<String> items1=Stream.of("findFirst","Example","Stream","Java8");
Stream<String> items2=Stream.of();
  
Optional<String> op1 = items1.findFirst();   
Optional<String> op2 = items2.findFirst();  


The Optional.isPresent() method


The ispresent() method of the optional object returns true if there is a value present,
otherwise it returns false.

System.out.println(op1.isPresent()); //true
System.out.println(op2.isPresent()); //false



The Optional.get() method

The get() method of the Optional object returns the value if a value is present in this Optional
object, otherwise throws NoSuchElementException.

System.out.println(op1.get()); //findFirst
System.out.println(op2.get()); //java.util.NoSuchElementException: No value present



The Optional.orElse() method


If a value is present in this optional then it is returned else it returns the replacement.
Since the 1st optional object has a value thus the value is returned.
The second optional does not have a value and thus the replacement "Hello" is returned.

System.out.println(op1.orElse("Hello"));  // findFirst
System.out.println(op2.orElse("Hello"));  // Hello



The Optional.orElseGet() method

Return the value if present, otherwise invoke supplied object and return the result of that invocation.
Here in the first case op1 has value hence the value is returned.
In the case of op2, there is no value and it will call the supplier.get() method by default.

Supplier<String> supplier=new Supplier<String>() {

   @Override
   public String get() {
    
    return "This is a replacement";
   }
  };
System.out.println(op1.orElseGet(supplier));  // findFirst
System.out.println(op2.orElseGet(supplier));  // This is a replacement



The Optional.orElseThrow() method

The orElseThrow() method of the Optional class returns the contained value, if present,
otherwise throw an exception to be created by the provided supplier.

System.out.println(op1.orElseThrow(NullPointerException::new));  // findFirst
System.out.println(op2.orElseThrow(NullPointerException::new));  // java.lang.NullPointerException



The Optional.filter() method

The filter() method in the Optional class is used to filter the data based on a given condition.
If this condition is met then it returns an Optional object defining its value.
Else if the filter condition is not met it will return a Optional.empty object.

System.out.println(op1);                                   //Optional[findFirst]
System.out.println(op1.filter(x -> x.contains("First")));  // Optional[findFirst]
System.out.println(op1.filter(x -> x.contains("Second"))); // Optional.empty



The Optional.of() method

The of() method of the optional class returns an Optional with the specified present non-null value.
It is to be noted here that the value supplied must not be NULL in any situation else we will get a NullPointerException in those cases. If we have situations where the supplied value
may be null then we must use ofNullable() instead.

Optional<String> op1 = Optional.of("Hello");
System.out.println(op1.get());  // Hello



The Optional.ofNullable() method

The ofznullable() method in Optional class returns an Optional describing the specified value,
if non-null, otherwise returns an empty Optional.Unlike of() it accepts NULL values.
If the Null value is supplied then it returns an empty Optional object.

Optional<String> op1 = Optional.ofNullable("Hello");
System.out.println(op1);  // Optional[Hello]

  
Optional<String> op2 = Optional.ofNullable(null);
System.out.println(op2);  // Optional.empty



The Optional.empty() method

The empty() method of the Optional class returns an empty Optional instance.
No value is present for this Optional.
It makes the Optional drop its value and makes it empty.

Optional<String> op1 = Optional.ofNullable("Hello");
System.out.println(op1);  // Optional[Hello]
  
Optional<String> op2 = op1.empty();
System.out.println(op2);  // Optional.empty



In conclusion the Optional is a container object which may or may not contain a non-null value.
If a value is present, isPresent() will return true and get() will return the value.

Stream Collectors Example in Java 8 : toList, toCollection, summingInt, groupingBy

The collect operation in stream is a handy terminal operation which is used to accumulate or convert a stream in to collections like List, Set Or Map.

It can be used to accumulate data present in a stream and convert into a list or a similar collection.
Similarly we can summarize data according to various criteria.

A collect operation is a combination of 4 elements namely supplier, an accumulator, a combiner and a finisher.
But since Java 8 uses inbuilt collectors, we do not need to implement one for most of our daily operations.


Here are a list of Methods explained below:
   1.   Collectors.toList()
   2.   Collectors.toCollection()
   3.   Collectors.summingInt()
   4.   Collectors.averagingDouble() and Collectors.averagingInt()
   5.   Collectors.groupingBy()


Lets the fun begin!!
We will create a List of Employee Objects to explain this tutorial.
The Employee class looks like this. It has a constructor and some getters and setters. Simple right?!!

package codermag.net.java8;

public class Employee {
 public String name;
 public int age;

 Employee(String name, int age) {
  this.setName(name);
  this.setAge(age);
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 @Override
 public String toString() {
  return getName();
 }
}


Now lets us look at the program below:


 List<Employee> employees = new ArrayList<Employee>();
  employees.add(new Employee("John", 35));
  employees.add(new Employee("Wendy", 43));
  employees.add(new Employee("Scott", 22));
  employees.add(new Employee("Joe", 17));
  employees.add(new Employee("Brad", 43));

  Stream<Employee> employeeStream = employees.stream();




1. Lets collect all the Employee Names and collect them in a List

The toList() operation in one of the basic operations of the Collectors class.
The toList() function in Collectors helps to convert a Stream to a List as shown below.

  // Accumulate names into a List
  List<String> listOfNames = employeeStream
                                   .map(Employee::getName)
                                   .collect(Collectors.toList());

System.out.println(listOfNames ); //[John, Wendy, Scott, Joe, Brad]




2. Lets filter names starting with the letter 'J'.


  // Filter names starting with 'J'
  List<String> listOfNamesStartingWithJ = employeeStream
                                              .filter(x -> x.getName().startsWith("J"))
                                              .map(Employee::getName)
                                              .collect(Collectors.toList());  

System.out.println(listOfNamesStartingWithJ); //[John, Joe]



3. Get the List of person objects whose name starts with 'J'.

For this case we are introducing an intermediate filter() method to filter data based on criteria.

List<Employee> listOfPersons = employeeStream
                                 .filter(x -> x.name.startsWith("J"))
                                 .collect(Collectors.toList());  

System.out.println(listOfPersons); //[John, Joe]




4. Lets sort the names using TreeSet.

A similar operation is toCollection() operation of Collectors class in Java 8.
Unlike the toList() Collector class, this is more generalized method for converting to collections.

  // Accumulate names into a TreeSet
  Set<String> setOfName = employeeStream
                                  .map(Employee::getName)
                                  .collect(Collectors.toCollection(TreeSet::new));

System.out.println(setOfName);  //[Brad, Joe, John, Scott, Wendy]




5. Get the sum of ages of all Employees.

Collectors in Java 8 are versatile and there are various utility methods which makes our
life much more simplier. For example the summingInt() of Collectors class in Java 8 lets you
calculate the sum of attributes of Stream data.

      int totalAge = employeeStream
                           .collect(Collectors.summingInt(Employee::getAge));
  
  System.out.println(totalAge); //10



6. Get the average of the ages of all employees.

Collectors class in Java 8 has functions like averagingDouble() and averagingInt()
to directly calculate the average of nummeric values.

Double averageAge=employeeStream
                        .collect(Collectors.averagingDouble(emp -> emp.age));
  
System.out.println(averageAge); // 32.0




7. Group by a particular attribute.

In java 8 Collectors, probably one of the most talked about method is the groupingBy() method.
The groupingBy() method in Collectors class in Java 8 lets you group data based on criterias set by you.
For example the following method uses the groupingBy() Collectors class method to group employees based
on their ages.

Map<Integer, List<Employee>> empMap = employeeStream
                                          .collect(Collectors.groupingBy(x -> x.age));

  empMap.forEach((age, empList) -> System.out.format(
    "Employees of age %s are : %s\n", age, empList));


/*
Employees of age 17 are : [Joe]
Employees of age 35 are : [John]
Employees of age 22 are : [Scott]
Employees of age 43 are : [Wendy, Brad]
*/