Monday, May 27, 2019

Java String getChars()​ Method Example

1. Overview

In this quick tutorial, We'll learn about String getChars​ method with examples. As well will take a look at internally how getChars​ method implemented and works.

Java String getChars​ Method Example


2. getChars​

This method copies the characters from this string into the destination character array. Also getChars​() method copies only a specified range of characters into new char array.
Source String start index, end index and destination array start index can be configured.

Removing All Duplicate Values from ArrayList including Java 8 Streams

1. Overview

In this tutorial, We'll learn how to clean up the duplicate elements from ArrayList. Many of the scenarios we do encounter the same in real time projects. But, this can be resolved in many ways.

We will start with Set first then next using new List with using built in method contains() before adding each value to newList.

Next, will see duplicate elements removal with new java 8 concept Streams.

Then later, interestingly we have a list with Employee objects. Employee has id and name. Some Employee objects are added to list. Later realized that list has now duplicate employee based on the id. Now how to remove custom duplicate objects from ArrayList.

Removing All Duplicate Values from ArrayList including Java 8 Streams

Friday, May 24, 2019

Fix to Invalid byte tag in constant pool: 15 in Tomcat 7+ Java 8

1. Overview

ClassFormatException: Invalid byte tag in constant pool: 15 solution:
I was working with java version 1.7 and Apache Tomcat/7.0.12.. I have updated java version to 1.8(C:\Program Files\Java\jdk1.8.0_51)

I was eagerly waiting to work with java 8 features. I just restarted my tomcat server.. then given stack trace below exception.




Invalid byte tag in constant pool 15

Iterate Map in Java 8 Steam API (Lamda Expression) and Older JDK

1. Overview

In this tutorial, We'll learn How to Iterate Map and How to Iteration HashMap in Java using various ways.

Iterating is very common process in any programming language using very basic for loop.

There are 6 different ways to extract or loop over Map in java such as using enhanced for loop, Iterator using EntrySet, Java 8 and stream API.

Most exciting is about lambda part and most of the projects are already migrated to Java 8 but may not be using full features of Java 8.

Iterate Map or HashMap in Java.PNG


As all of us know, ArrayList is directly iterated using Iterator but it is not possible encase of Map because Map is not under Collection interface.


We must know about internals of how hashmap works in java. HashMap creates internally Hashset and added Entry objects into Hashset.

Map.Entry object looks like below.

   static class Node implements Map.Entry {
   final int hash;
   final K key;
   V value;
   Node next;

  // constructor, setters and getters

  }

In all examples today will be executed on the below input. All these values are stored in set in the form of Node<String, String> which is an Map.Entry object.

Map hashMap = new HashMap<>();
hashMap.put("Map", "HashMap");
hashMap.put("Set", "Hashset");
hashMap.put("List", "ArrayList");

2. Map.entrySet() using for each


Map has a method entryset() which returns the Set object. In our case, it is Set<Entry<String, String>> and this holds Entry<String, String> objects.

Now we will iterate through enhanced for loop this set. See the code below.


for (Map.Entry entry : hashMap.entrySet())
 System.out.println("Key(Interface) = " + entry.getKey() + ", Value(Implementation class) = " + entry.getValue());
}

First, retrieving the each object from set in the form of entry object and then next calling getKey() to get the key from Node/Entry object and getValue() method to get the value of the corresponding key.

Output:

Key(Interface) = Set, Value(Implementation class) = Hashset
Key(Interface) = List, Value(Implementation class) = ArrayList
Key(Interface) = Map, Value(Implementation class) = HashMap

This methodology is commonly used by all programmers if want to retrieve both key and value at the same time.

3. keySet() and values() methods

We might need to get the only keys some scenario where values are not required and vice versa. In these type of situations, we'll try to minimize getting entire key-value pair. Map has provided methods to get only keys or values by invoking methods keyset() and values().


// Retrieving only keys
for (String interfaceName : hashMap.keySet()) {
 System.out.println("Key(Interface): " + interfaceName);
}

// Retrieving only values
for (String ImplementationClassName : hashMap.values()) {
 System.out.println("Value(Implementation class): " + ImplementationClassName);
}

Output:

Key(Interface): Set
Key(Interface): List
Key(Interface): Map
Value(Implementation class): Hashset
Value(Implementation class): ArrayList
Value(Implementation class): HashMap

4. entrySet().iterator()

Next approach is as Similar to Section 2, Here as well first need to call the entrySet() method which returns set.
Now we have set object and set has a method iterate().

See the below code.

Set> entrySet = hashMap.entrySet();
Iterator> iterator = entrySet.iterator();

while (iterator.hasNext()) {
 Entry entry = iterator.next();
 System.out.println(
   "Key(Interface) = " + entry.getKey() + ", Value(Implementation class) = " + entry.getValue());
}

We'll now iterate tradition mechanism using hasNext() and next() methods.

hasNext(): returns true if next element is present in the collection. Otherwise false.
next(): returns next object from collection.

Output will same as in section 2.

5. Lamda Expression - forEach()


Java 8 introduced Lamda concept which is in funcitonal programming. Lamda's reduces code to very minimal to our core logic and remaing take care by Lamda.

Now take a look at the below code using Map.forEach() method. forEach method takes BiConsumer as argument and calls it's accept() method.

hashMap.forEach((k, v) -> System.out.println("Key(Interface) = " + k + ", Value(Implementation class) = " + v));

All of this logic now bacame to single line. This is the power of lambda.

(k, v) is passed to the accept() method and adds System.out.println() inside method body as below.


accept(String k, String v){
 System.out.println("Key(Interface) = " + k + ", Value(Implementation class) = " + v)
}

Output will be same as section 2.

Look at interesting article on "Iterating String Array Examples"

6. Stream API

Stream api also introduced in Java 8 and most powerful rich feature. Stream api primarly designed for collection api and provides the way to process collection sequentially and parellel.

Iterating map using Stream api
is simple. But streams are extremly useful when we do aggregation operations.

First invoke entrySet().stream() method which inturn returns Stream object.

Stream> entriesStream = hashMap.entrySet().stream();

Next, Stream intreface has void forEach(Consumer<? super T> action) method. This forEach method iterates the Entry objects that are in the entrySet(). See the below code.

entriesStream.forEach(entry -> System.out.println(entry.getKey() + " - " + entry.getValue()));

Output:

Set - Hashset
List - ArrayList
Map - HashMap

We can still further rewrite the above code into single line as below which will produce the same output.

hashMap.entrySet().stream().forEach(entry -> System.out.println(entry.getKey() + " - " + entry.getValue()));

7. Get Key and Search for it's value

As of now, we get both key and value at the same time in all above methods discussed as of now. But there is a way to get keys first and iterate keys to get value for each key by calling map.get(key) method.

for (String key : hashMap.keySet()) {
 String value = hashMap.get(key);
 System.out.println(key + " - " + value);
}

This code works fine and generate the expected output but this code is not efficient to run through huge key-value pair maps.

This solutin is not suggested and caught error complaining stating "WMI_WRONG_MAP_ITERATOR" in FingBugs because doing loop up for each key in map again calling get() method.
Use any one of above methods that will solve this problem.

8. Conclusion


In this tutoril, We've seen all possible ways on how to iterate through a map in java including java 8 stream concpets.

Further more covered Stream api forEach and map forEach methods with examples and inefficient way of iterating map which is not suggested by FindBugs.

All codes shown in this tutorail are available on GitHub.

Thursday, May 23, 2019

Find Unique and Duplicates Values From Two Lists

1. Overview

In this tutorial, We'll learn how to find the unique values from two lists and how to find all common or duplicates values from two lists.

We'll demonstrate using two ArrayList's to find out unique and duplicates objects in it.

To achieve our requirement, we must compare values in both list. Either we can run the loop through each list or we can use list api built in methods. We'll explore using built in api methods such as contains(), retailAll() and removeAll() methods.




Find Unique and Duplicates From Two Lists

Wednesday, May 22, 2019

How To Print 1 to 100 Numbers Without Using Any Loop statements

1. Overview

this tutorial, We'll learn how to print 1 to 100 without using loop statements.

Couple of year back, My friend was asked this question in interview. He has given many tries but finally he could give the answer using recursive approach. This interview question will be asked to check how we understand the concepts and how we are using it on problem.

Print 1 to 100 Numbers Without Using Any Loop statements
Actually this can be done using any loop statements such as For Loop or While Loop. But, we'll see using normal and recursive approach.

2. Normal Approach


In the normal approach, printing numbers from 1 to 100 is done by for or while loop running from pointer 1 to 100.

2.1 for loop

A comprehensive guide to For Loop with Examples.


for (int i = 1; i <= 100; i++) {
 System.out.println(i);
}

2.2 While loop

A comprehensive guide to While Loop with Examples.

int j = 1;
while (j <= 100) {
 System.out.println(j);
 j++;
}

3. Recursive Approach

Recursion: A method calls itself again and again to resolve a problem that is until a given condition is met.

We will implement in Java, C++ and Python programming languages.
Here recursive approach starts from number 100 to 1 because it creates a stack for each self call. First call for 100 will be placed in the stack and 99 next ... and so on.. for 1 st num method call be on top of stack. Once seeing the program, you will be getting clear idea.

3.1 Java


public void printNnumber(int toNumber) {
 if (toNumber > 0) {
  printNnumber(toNumber - 1);
  System.out.print(toNumber + " ");
 }
 return;
}

3.2 C++


public: 
void printNnumber(unsigned int toNumber) 
{ 
    if(toNumber > 0) 
    { 
        printNnumber(toNumber - 1); 
        cout << toNumber << " "; 
    } 
    return; 
} 
}; 

3.3 Python

indentation is important in Python.

def printNnumber(toNumber): 
    if toNumber > 0: 
        printNnumber(toNumber - 1) 
        print(toNumber, end = ' ') 

4. Output

Output for all programs above should be same. We have tested all these programs in latest versions.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 

5. Conclusion

In this tutorial, we've seen printing the numbers from 1 to any without using loop.

Further article, implementation is done in java, c++ and python 3.

The same logic can be used on any pattern such print your name 100 times without using for loop or print pattern without loop, print number series etc.

All codes are shown here are available on GitHub.

Tuesday, May 21, 2019

Tomcat 7+ Java 8 : Invalid byte tag in constant pool: 15 and invalid byte tag in constant pool 19

1. Overview

ClassFormatException: Invalid byte tag in constant pool: 15, 18, 19 solution:
I was working with java version 1.7 and Apache Tomcat/7.0.12.. I have updated java version to 1.8(C:\Program Files\Java\jdk1.8.0_51)

I was eagerly waiting to work with java 8 features. I just restarted my tomcat server.. then given stack trace below exception.



Invalid byte tag in constant pool 15

2. Exeception occurred after Tomcat 7 restart:

Aug 22, 2015 10:57:05 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.12
org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 15
    at org.apache.tomcat.util.bcel.classfile.Constant.readConstant(Constant.java:131)
    at org.apache.tomcat.util.bcel.classfile.ConstantPool.(ConstantPool.java:60)
    at org.apache.tomcat.util.bcel.classfile.ClassParser.readConstantPool(ClassParser.java:209)
    at org.apache.tomcat.util.bcel.classfile.ClassParser.parse(ClassParser.java:119)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:1917)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:1806)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1765)
    at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:1751)
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1255)
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:882)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:317)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:89)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5081)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:774)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:291)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:727)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:620)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:303)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:431)

I have surprised.. what was this new problem never encountered. checked tomcat official website. Stated that "The "offical answer" is that Tomcat 7 runs on Java 8, see http://tomcat.apache.org/whichversion.html("Java version 6 and later")."

3. Solution 1 :

However, if annotation scanning is enabled (metadata-complete="true" in web.xml) there are some issues due to BCEL (not able to process the new Java 8 byte codes). You will get exceptions like (at least with Tomcat 7):

SEVERE: Unable to process Jar entry [jdk/nashorn/internal/objects/NativeString.class] from Jar [jar:file:/usr/lib/jvm/jdk1.8.0_5/jre/lib/ext/nashorn.jar!/] for annotations

org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 15
    at org.apache.tomcat.util.bcel.classfile.Constant.readConstant(Constant.java:131)
If not using annotation scanning, everything works fine, starting release 7.0.53 (updated compiler with better Java 8 support).

(UPDATE 2014-10-17) If your are using annotation scanning and your own code is not Java 8 based, another solution is to add the following line in /etc/tomcat7/catalina.properties (text added after "ant-launcher.jar" so part of property tomcat.util.scan.DefaultJarScanner.jarsToSkip):


junit.jar,junit-*.jar,ant-launcher.jar,\

jfxrt.jar,nashorn.jar
Tested with Tomcat 7.0.28 and Oracle JDK 8_25 on Debian 7.6.


4. Solution 2 :

Upgrade the tomcat version to Tomcat 7.0.65. Works well.


Solution 2 is simple, definitely works.

There are some more scenarios which causes the same problem which is below case and another case as well. We have provided other alternative solutions based many user experiences. Hope helps.

4.1 Problem: Tomcat 7 - Servlet 3.0: Invalid byte tag in constant pool:

I just switched the web.xml to servlet 3.0 (from a app running 2.4 previously) and now I'm seeing the following error (turned on fine logging for org.apache.tomcat.util):

Following is the problem requirements.

tomcat 7.0.16
Java 1.6.0_22
CentOS 5.6

4.2 Error occurred for ClassFormatException:



mtyson  FINE: Scanning JAR [file:/usr/java/jdk1.6.0_22/jre/lib/ext/jcharset.jar] from classpath
mtyson  Jul 19, 2011 10:04:40 AM org.apache.catalina.startup.HostConfig deployDirectory
mtyson  SEVERE: Error deploying web application directory ROOT
mtyson  org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 60


5. Solution 3:

It may not be your issue, but mine was the same as this one -- an old version of com.ibm.icu:icu4j. I solved the problem by changing by build configuration to exclude the older transitive dependencies and explicitly depending upon the latest version (4.8).

6. Solution 4:

Adding a attribute in the web application web.xml file to your web.xml should sort the issue (metadata-complete="true")

<web-app version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

         metadata-complete="true">

7. Solution 5:

I was facing the same issue from a week and resolved by simply replacing the icu4j.2.1.jar file with latest version of jar.


8. Conclusion


In this tutorial, We've seen in which scenario's ClassFormatException while working with tomcat + Java 8.
In further in this article, discussed most useful 5 solutions to solve this issue.
That's all.