diff --git a/guava21/README.md b/guava21/README.md
new file mode 100644
index 0000000000..8121cf2ea6
--- /dev/null
+++ b/guava21/README.md
@@ -0,0 +1,7 @@
+=========
+
+## Guava 21
+
+**Important**: Guava 21.0 requires Java 8. If you need Java 6, 7 or Android compatibility, use Guava 20.0 for now. Guava 22.0 and on will introduce a Java 6/Android compatible backport of Guava that includes all of the latest changes that don't require Java 8.
+
+Article 1 : Introduction to Guava21 common.collect package.
\ No newline at end of file
diff --git a/guava21/pom.xml b/guava21/pom.xml
new file mode 100644
index 0000000000..f393c65aec
--- /dev/null
+++ b/guava21/pom.xml
@@ -0,0 +1,41 @@
+
+
+ 4.0.0
+
+ com.baeldung.guava
+ tutorial
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+
+ com.google.guava
+ guava
+ 21.0
+
+
+
+
+ junit
+ junit
+ 4.11
+
+
+
+
+
+
\ No newline at end of file
diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/ComparatorsExamples.java b/guava21/src/main/java/com/baeldung/guava/tutorial/ComparatorsExamples.java
new file mode 100644
index 0000000000..6eb5c7f5ba
--- /dev/null
+++ b/guava21/src/main/java/com/baeldung/guava/tutorial/ComparatorsExamples.java
@@ -0,0 +1,27 @@
+package com.baeldung.guava.tutorial;
+
+import com.google.common.collect.Comparators;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+public class ComparatorsExamples {
+
+ public static void main(String[] args){
+
+ List integers = Arrays.asList(1,2,3,4,4,6,7,8,9,10);
+ //This will return true
+ boolean isInAscendingOrder = Comparators.isInOrder(integers, new AscedingOrderComparator());
+
+ System.out.println(isInAscendingOrder);
+
+ }
+
+ private static class AscedingOrderComparator implements Comparator {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return o1.compareTo(o2);
+ }
+ }
+}
diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/ConcatStreams.java b/guava21/src/main/java/com/baeldung/guava/tutorial/ConcatStreams.java
new file mode 100644
index 0000000000..ab95b85751
--- /dev/null
+++ b/guava21/src/main/java/com/baeldung/guava/tutorial/ConcatStreams.java
@@ -0,0 +1,11 @@
+package com.baeldung.guava.tutorial;
+
+import com.google.common.collect.Streams;
+
+import java.util.stream.Stream;
+
+public class ConcatStreams {
+ public static Stream concatStreams(Stream stream1, Stream stream2, Stream stream3){
+ return Streams.concat(stream1,stream2,stream3);
+ }
+}
diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/InternerBuilderExample.java b/guava21/src/main/java/com/baeldung/guava/tutorial/InternerBuilderExample.java
new file mode 100644
index 0000000000..6b935ba2a8
--- /dev/null
+++ b/guava21/src/main/java/com/baeldung/guava/tutorial/InternerBuilderExample.java
@@ -0,0 +1,19 @@
+package com.baeldung.guava.tutorial;
+
+import com.google.common.collect.Interner;
+import com.google.common.collect.Interners;
+
+import static com.google.common.collect.Interners.newBuilder;
+
+public class InternerBuilderExample {
+
+ public static void main(String[] args){
+ Interner interners = Interners.newBuilder()
+ .concurrencyLevel(2)
+ .strong()
+ .build();
+
+
+ }
+
+}
diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/MoreCollectorsExample.java b/guava21/src/main/java/com/baeldung/guava/tutorial/MoreCollectorsExample.java
new file mode 100644
index 0000000000..6cf4b6b0ac
--- /dev/null
+++ b/guava21/src/main/java/com/baeldung/guava/tutorial/MoreCollectorsExample.java
@@ -0,0 +1,17 @@
+package com.baeldung.guava.tutorial;
+
+import com.google.common.collect.MoreCollectors;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+public class MoreCollectorsExample {
+
+ public static void main(String[] args) {
+ List numbers = Arrays.asList(1);
+ Optional number = numbers.stream()
+ .map(e -> e * 2)
+ .collect(MoreCollectors.toOptional());
+ }
+}
diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/StreamsUtility.java b/guava21/src/main/java/com/baeldung/guava/tutorial/StreamsUtility.java
new file mode 100644
index 0000000000..4ec3b44ef4
--- /dev/null
+++ b/guava21/src/main/java/com/baeldung/guava/tutorial/StreamsUtility.java
@@ -0,0 +1,42 @@
+package com.baeldung.guava.tutorial;
+
+import com.google.common.collect.Streams;
+
+import java.util.*;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+
+public class StreamsUtility {
+
+ public static void main(String[] args){
+
+ List numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,11,12,13,14,15,16,17,18,19,20);
+ //Using Collection
+ Stream streamFromCollection = Streams.stream(numbers);
+ //Using Iterator
+ Stream streamFromIterator = Streams.stream(numbers.iterator());
+ //Using Iterable
+ Stream streamFromIterable = Streams.stream((Iterable) numbers);
+ //Using Optional
+ Stream streamFromOptional = Streams.stream(Optional.of(1));
+ //Using OptionalLong to LongStream
+ LongStream streamFromOptionalLong = Streams.stream(OptionalLong.of(1));
+ //Using OptionalInt to IntStream
+ IntStream streamFromOptionalInt = Streams.stream(OptionalInt.of(1));
+ //Using OptionalDouble to DoubleStream
+ DoubleStream streamFromOptionalDouble = Streams.stream(OptionalDouble.of(1.0));
+
+ Stream concatenatedStreams = Streams.concat(streamFromCollection,streamFromIterable,streamFromIterator);
+
+ List integers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
+ //This will return 10
+ Optional lastItem = Streams.findLast(integers.stream());
+
+ Streams.zip(
+ Stream.of("candy", "chocolate", "bar"),
+ Stream.of("$1", "$2","$3"),
+ (arg1, arg2) -> arg1 + ":" + arg2);
+ }
+}
diff --git a/guava21/src/test/java/ComparatorsUnitTests.java b/guava21/src/test/java/ComparatorsUnitTests.java
new file mode 100644
index 0000000000..f196c41a1b
--- /dev/null
+++ b/guava21/src/test/java/ComparatorsUnitTests.java
@@ -0,0 +1,76 @@
+import com.google.common.collect.Comparators;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+public class ComparatorsUnitTests {
+
+ @Test
+ public void isInOrderTest(){
+
+ List numbers = Arrays.asList(1,2,3,4,4,6,7,8,9,10);
+
+ boolean isInAscendingOrder = Comparators.isInOrder(numbers, new AscendingOrderComparator());
+
+ Assert.assertTrue(isInAscendingOrder);
+ }
+
+ @Test
+ public void isInStrictOrderTest(){
+
+ List numbers = Arrays.asList(1,2,3,4,3,6,7,8,9,10);
+
+ boolean isInAscendingOrder = Comparators.isInOrder(numbers, new AscendingOrderComparator());
+
+ Assert.assertFalse(isInAscendingOrder);
+ }
+
+
+ private class AscendingOrderComparator implements Comparator{
+
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return o1.compareTo(o2);
+ }
+
+ @Override
+ public Comparator reversed() {
+ return null;
+ }
+
+ @Override
+ public Comparator thenComparing(Comparator super Integer> other) {
+ return null;
+ }
+
+ @Override
+ public Comparator thenComparing(Function super Integer, ? extends U> keyExtractor, Comparator super U> keyComparator) {
+ return null;
+ }
+
+ @Override
+ public > Comparator thenComparing(Function super Integer, ? extends U> keyExtractor) {
+ return null;
+ }
+
+ @Override
+ public Comparator thenComparingInt(ToIntFunction super Integer> keyExtractor) {
+ return null;
+ }
+
+ @Override
+ public Comparator thenComparingLong(ToLongFunction super Integer> keyExtractor) {
+ return null;
+ }
+
+ @Override
+ public Comparator thenComparingDouble(ToDoubleFunction super Integer> keyExtractor) {
+ return null;
+ }
+ }
+}
diff --git a/guava21/src/test/java/GauavaStreamsTests.java b/guava21/src/test/java/GauavaStreamsTests.java
new file mode 100644
index 0000000000..09e3e29b47
--- /dev/null
+++ b/guava21/src/test/java/GauavaStreamsTests.java
@@ -0,0 +1,155 @@
+import com.google.common.collect.Streams;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.*;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+
+public class GauavaStreamsTests {
+
+ List numbers;
+
+ @Before
+ public void setUp(){
+ numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,11,12,13,14,15,16,17,18,19,20);
+ }
+
+
+ @Test
+ public void createStreamsWithCollection(){
+ //Deprecated API to create stream from collection
+ Stream streamFromCollection = Streams.stream(numbers);
+
+ //Assert.assertNotNull(streamFromCollection);
+ StreamUtility.assertStreamEquals(streamFromCollection, numbers.stream());
+ }
+
+ @Test
+ public void createStreamsWithIterable(){
+ Iterable numbersIterable = (Iterable) numbers;
+
+ Stream streamFromIterable = Streams.stream(numbersIterable);
+
+ Assert.assertNotNull(streamFromIterable);
+ StreamUtility.assertStreamEquals(streamFromIterable, numbers.stream());
+ }
+
+ @Test
+ public void createStreamsWithIterator(){
+ Iterator numbersIterator = numbers.iterator();
+
+ Stream streamFromIterator = Streams.stream(numbersIterator);
+
+ Assert.assertNotNull(streamFromIterator);
+ StreamUtility.assertStreamEquals(streamFromIterator, numbers.stream());
+ }
+
+ @Test
+ public void createStreamsWithOptional(){
+
+ Stream streamFromOptional = Streams.stream(Optional.of(1));
+
+ Assert.assertNotNull(streamFromOptional);
+ Assert.assertEquals(streamFromOptional.count(), 1);
+ }
+
+ @Test
+ public void createStreamsWithOptionalLong(){
+
+ LongStream streamFromOptionalLong = Streams.stream(OptionalLong.of(1));
+
+ Assert.assertNotNull(streamFromOptionalLong);
+ Assert.assertEquals(streamFromOptionalLong.count(), 1);
+ }
+
+ @Test
+ public void createStreamsWithOptionalInt(){
+
+ IntStream streamFromOptionalInt = Streams.stream(OptionalInt.of(1));
+
+ //Assert.assertNotNull(streamFromOptionalInt);
+ Assert.assertEquals(streamFromOptionalInt.count(), 1);
+ }
+
+ @Test
+ public void createStreamsWithOptionalDouble(){
+
+ DoubleStream streamFromOptionalDouble = Streams.stream(OptionalDouble.of(1.0));
+
+ //Assert.assertNotNull(streamFromOptionalDouble);
+ Assert.assertEquals(streamFromOptionalDouble.count(), 1);
+
+ }
+
+ @Test
+ public void concatStreamsOfSameType(){
+ Stream oddNumbers = Arrays.asList(1,3,5,7,9,11,13,15,17,19).stream();
+ Stream evenNumbers = Arrays.asList(2,4,6,8,10,12,14,16,18,20).stream();
+
+ Stream combinedStreams = Streams.concat(oddNumbers,evenNumbers);
+
+ //Assert.assertNotNull(combinedStreams);
+ StreamUtility.assertStreamEquals(combinedStreams, Stream.concat(oddNumbers, evenNumbers));
+ }
+
+ @Test
+ public void concatStreamsOfTypeLongStream(){
+ LongStream firstTwenty = LongStream.range(1,20);
+ LongStream nextTwenty = LongStream.range(21,40);
+
+ LongStream combinedStreams = Streams.concat(firstTwenty,nextTwenty);
+
+ Assert.assertNotNull(combinedStreams);
+ StreamUtility.assertStreamEquals(combinedStreams, LongStream.concat(firstTwenty, nextTwenty));
+ }
+
+ @Test
+ public void concatStreamsOfTypeIntStream(){
+ IntStream firstTwenty = IntStream.range(1,20);
+ IntStream nextTwenty = IntStream.range(21,40);
+
+ IntStream combinedStreams = Streams.concat(firstTwenty,nextTwenty);
+
+ Assert.assertNotNull(combinedStreams);
+ StreamUtility.assertStreamEquals(combinedStreams, IntStream.concat(firstTwenty, nextTwenty));
+ }
+
+
+ @Test
+ public void findLastOfStream(){
+ Optional lastElement = Streams.findLast(numbers.stream());
+
+ Assert.assertNotNull(lastElement.get());
+ Assert.assertEquals(lastElement.get(), numbers.get(20));
+ }
+
+ @Test
+ public void mapWithIndexTest(){
+ Stream stringSream = Stream.of("a","b","c");
+
+ Stream mappedStream = Streams.mapWithIndex(stringSream,(str,index) -> str +":"+ index);
+
+ //Assert.assertNotNull(mappedStream);
+ Assert.assertEquals(mappedStream.findFirst().get(), "a:0");
+
+ }
+
+ @Test
+ public void streamsZipTest(){
+ Stream stringSream = Stream.of("a","b","c");
+ Stream intStream = Stream.of(1,2,3);
+ Stream mappedStream = Streams.zip(stringSream,intStream, (str,index) -> str +":"+ index);
+
+ //Assert.assertNotNull(mappedStream);
+ Assert.assertEquals(mappedStream.findFirst().get(), "a:1");
+
+ }
+
+
+
+
+}
diff --git a/guava21/src/test/java/InternBuilderUnitTests.java b/guava21/src/test/java/InternBuilderUnitTests.java
new file mode 100644
index 0000000000..513b44f249
--- /dev/null
+++ b/guava21/src/test/java/InternBuilderUnitTests.java
@@ -0,0 +1,19 @@
+import com.google.common.collect.Interner;
+import com.google.common.collect.Interners;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class InternBuilderUnitTests {
+
+ @Test
+ public void interBuilderTest(){
+
+ Interner interners = Interners.newBuilder()
+ .concurrencyLevel(2)
+ .strong()
+ .build();
+
+ Assert.assertNotNull(interners);
+ }
+
+}
diff --git a/guava21/src/test/java/MoreCollectorsUnitTests.java b/guava21/src/test/java/MoreCollectorsUnitTests.java
new file mode 100644
index 0000000000..956331e25f
--- /dev/null
+++ b/guava21/src/test/java/MoreCollectorsUnitTests.java
@@ -0,0 +1,36 @@
+import com.google.common.collect.MoreCollectors;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+public class MoreCollectorsUnitTests {
+
+ @Test
+ public void toOptionalTest(){
+
+ List numbers = Arrays.asList(1);
+
+ Optional number = numbers.stream()
+ .map( e -> e*2)
+ .collect(MoreCollectors.toOptional());
+
+ Assert.assertEquals(number.get(),new Integer(2));
+ }
+
+
+ @Test
+ public void onlyElementTest(){
+ List numbers = Arrays.asList(1);
+
+ Integer number = numbers.stream()
+ .map( e -> e*2)
+ .collect(MoreCollectors.onlyElement());
+
+ Assert.assertEquals(number,new Integer(2));
+ }
+
+
+}
diff --git a/guava21/src/test/java/StreamUtility.java b/guava21/src/test/java/StreamUtility.java
new file mode 100644
index 0000000000..91a03be48d
--- /dev/null
+++ b/guava21/src/test/java/StreamUtility.java
@@ -0,0 +1,66 @@
+import org.junit.Assert;
+
+import java.util.Iterator;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+
+public class StreamUtility {
+
+ public static boolean assertStreamEquals(Stream stream1, Stream stream2){
+
+ Iterator iterator1 = stream1.iterator();
+ Iterator iterator2 = stream2.iterator();
+
+ while (iterator1.hasNext()){
+ Assert.assertEquals(iterator1.next(), iterator2.next());
+ }
+
+ Assert.assertFalse(iterator2.hasNext());
+
+ return true;
+ }
+
+ public static boolean assertStreamEquals(LongStream stream1, LongStream stream2) {
+
+ Iterator iterator1 = stream1.iterator();
+ Iterator iterator2 = stream2.iterator();
+
+ while (iterator1.hasNext()){
+ Assert.assertEquals(iterator1.next(), iterator2.next());
+ }
+
+ Assert.assertFalse(iterator2.hasNext());
+
+ return true;
+ }
+
+ public static boolean assertStreamEquals(DoubleStream stream1, DoubleStream stream2) {
+
+ Iterator iterator1 = stream1.iterator();
+ Iterator iterator2 = stream2.iterator();
+
+ while (iterator1.hasNext()){
+ Assert.assertEquals(iterator1.next(), iterator2.next());
+ }
+
+ Assert.assertFalse(iterator2.hasNext());
+
+ return true;
+ }
+
+ public static boolean assertStreamEquals(IntStream stream1, IntStream stream2) {
+
+ Iterator iterator1 = stream1.iterator();
+ Iterator iterator2 = stream2.iterator();
+
+ while (iterator1.hasNext()){
+ Assert.assertEquals(iterator1.next(), iterator2.next());
+ }
+
+ Assert.assertFalse(iterator2.hasNext());
+
+ return true;
+ }
+}