diff --git a/core-java-8/findItemsBasedOnValues/.gitignore b/core-java-8/findItemsBasedOnValues/.gitignore deleted file mode 100644 index ae3c172604..0000000000 --- a/core-java-8/findItemsBasedOnValues/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bin/ diff --git a/core-java-8/findItemsBasedOnValues/src/findItems/FindItemsBasedOnValues.java b/core-java-collections/src/test/java/com/baeldung/findItems/FindItemsBasedOnOtherStreamUnitTest.java similarity index 63% rename from core-java-8/findItemsBasedOnValues/src/findItems/FindItemsBasedOnValues.java rename to core-java-collections/src/test/java/com/baeldung/findItems/FindItemsBasedOnOtherStreamUnitTest.java index a0dcdddd85..326ea9fbe4 100644 --- a/core-java-8/findItemsBasedOnValues/src/findItems/FindItemsBasedOnValues.java +++ b/core-java-collections/src/test/java/com/baeldung/findItems/FindItemsBasedOnOtherStreamUnitTest.java @@ -1,93 +1,89 @@ -package findItems; - -import static org.junit.Assert.assertEquals; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.Test; - -public class FindItemsBasedOnValues { - - List EmplList = new ArrayList(); - List deptList = new ArrayList(); - - public static void main(String[] args) throws ParseException { - FindItemsBasedOnValues findItems = new FindItemsBasedOnValues(); - findItems.givenDepartmentList_thenEmployeeListIsFilteredCorrectly(); - } - - @Test - public void givenDepartmentList_thenEmployeeListIsFilteredCorrectly() { - Integer expectedId = 1002; - - populate(EmplList, deptList); - - List filteredList = EmplList.stream() - .filter(empl -> deptList.stream() - .anyMatch(dept -> dept.getDepartment() - .equals("sales") && empl.getEmployeeId() - .equals(dept.getEmployeeId()))) - .collect(Collectors.toList()); - - assertEquals(expectedId, filteredList.get(0) - .getEmployeeId()); - } - - private void populate(List EmplList, List deptList) { - Employee employee1 = new Employee(1001, "empl1"); - Employee employee2 = new Employee(1002, "empl2"); - Employee employee3 = new Employee(1003, "empl3"); - - Collections.addAll(EmplList, employee1, employee2, employee3); - - Department department1 = new Department(1002, "sales"); - Department department2 = new Department(1003, "marketing"); - Department department3 = new Department(1004, "sales"); - - Collections.addAll(deptList, department1, department2, department3); - } -} - -class Employee { - Integer employeeId; - String employeeName; - - public Employee(Integer employeeId, String employeeName) { - super(); - this.employeeId = employeeId; - this.employeeName = employeeName; - } - - public Integer getEmployeeId() { - return employeeId; - } - - public String getEmployeeName() { - return employeeName; - } - -} - -class Department { - Integer employeeId; - String department; - - public Department(Integer employeeId, String department) { - super(); - this.employeeId = employeeId; - this.department = department; - } - - public Integer getEmployeeId() { - return employeeId; - } - - public String getDepartment() { - return department; - } - +package com.baeldung.findItems; + +import static org.junit.Assert.assertEquals; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Test; + +public class FindItemsBasedOnOtherStreamUnitTest { + + private List employeeList = new ArrayList(); + + private List departmentList = new ArrayList(); + + @Test + public void givenDepartmentList_thenEmployeeListIsFilteredCorrectly() { + Integer expectedId = 1002; + + populate(employeeList, departmentList); + + List filteredList = employeeList.stream() + .filter(empl -> departmentList.stream() + .anyMatch(dept -> dept.getDepartment() + .equals("sales") && empl.getEmployeeId() + .equals(dept.getEmployeeId()))) + .collect(Collectors.toList()); + + assertEquals(expectedId, filteredList.get(0) + .getEmployeeId()); + } + + private void populate(List EmplList, List deptList) { + Employee employee1 = new Employee(1001, "empl1"); + Employee employee2 = new Employee(1002, "empl2"); + Employee employee3 = new Employee(1003, "empl3"); + + Collections.addAll(EmplList, employee1, employee2, employee3); + + Department department1 = new Department(1002, "sales"); + Department department2 = new Department(1003, "marketing"); + Department department3 = new Department(1004, "sales"); + + Collections.addAll(deptList, department1, department2, department3); + } +} + +class Employee { + private Integer employeeId; + private String employeeName; + + Employee(Integer employeeId, String employeeName) { + super(); + this.employeeId = employeeId; + this.employeeName = employeeName; + } + + Integer getEmployeeId() { + return employeeId; + } + + public String getEmployeeName() { + return employeeName; + } + +} + +class Department { + private Integer employeeId; + private String department; + + Department(Integer employeeId, String department) { + super(); + this.employeeId = employeeId; + this.department = department; + } + + Integer getEmployeeId() { + return employeeId; + } + + String getDepartment() { + return department; + } + } \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/modulo/ModuloUnitTest.java b/core-java/src/test/java/com/baeldung/modulo/ModuloUnitTest.java new file mode 100644 index 0000000000..8b3685adf3 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/modulo/ModuloUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.modulo; + +import org.junit.Test; +import static org.assertj.core.api.Java6Assertions.*; + +public class ModuloUnitTest { + + @Test + public void whenIntegerDivision_thenLosesRemainder(){ + assertThat(11 / 4).isEqualTo(2); + } + + @Test + public void whenDoubleDivision_thenKeepsRemainder(){ + assertThat(11 / 4.0).isEqualTo(2.75); + } + + @Test + public void whenModulo_thenReturnsRemainder(){ + assertThat(11 % 4).isEqualTo(3); + } + + @Test(expected = ArithmeticException.class) + public void whenDivisionByZero_thenArithmeticException(){ + double result = 1 / 0; + } + + @Test(expected = ArithmeticException.class) + public void whenModuloByZero_thenArithmeticException(){ + double result = 1 % 0; + } + + @Test + public void whenDivisorIsOddAndModulusIs2_thenResultIs1(){ + assertThat(3 % 2).isEqualTo(1); + } + + @Test + public void whenDivisorIsEvenAndModulusIs2_thenResultIs0(){ + assertThat(4 % 2).isEqualTo(0); + } + + @Test + public void whenItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds(){ + int QUEUE_CAPACITY= 10; + int[] circularQueue = new int[QUEUE_CAPACITY]; + int itemsInserted = 0; + for (int value = 0; value < 1000; value++) { + int writeIndex = ++itemsInserted % QUEUE_CAPACITY; + circularQueue[writeIndex] = value; + } + } + +} diff --git a/guava-collections/.gitignore b/guava-collections/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/guava-collections/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/guava-collections/README.md b/guava-collections/README.md new file mode 100644 index 0000000000..eb1eb1d35c --- /dev/null +++ b/guava-collections/README.md @@ -0,0 +1,20 @@ +========= + +## Guava and Hamcrest Cookbooks and Examples + + +### Relevant Articles: +- [Guava Collections Cookbook](http://www.baeldung.com/guava-collections) +- [Guava Ordering Cookbook](http://www.baeldung.com/guava-order) +- [Hamcrest Collections Cookbook](http://www.baeldung.com/hamcrest-collections-arrays) +- [Partition a List in Java](http://www.baeldung.com/java-list-split) +- [Filtering and Transforming Collections in Guava](http://www.baeldung.com/guava-filter-and-transform-a-collection) +- [Guava – Join and Split Collections](http://www.baeldung.com/guava-joiner-and-splitter-tutorial) +- [Guava – Lists](http://www.baeldung.com/guava-lists) +- [Guava – Sets](http://www.baeldung.com/guava-sets) +- [Guava – Maps](http://www.baeldung.com/guava-maps) +- [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap) +- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) +- [Guide to Guava RangeMap](http://www.baeldung.com/guava-rangemap) +- [Guide to Guava MinMaxPriorityQueue and EvictingQueue](http://www.baeldung.com/guava-minmax-priority-queue-and-evicting-queue) +- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) \ No newline at end of file diff --git a/guava-collections/pom.xml b/guava-collections/pom.xml new file mode 100644 index 0000000000..a717023156 --- /dev/null +++ b/guava-collections/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + com.baeldung + guava-collections + 0.1.0-SNAPSHOT + guava-collections + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + org.hamcrest + java-hamcrest + ${java-hamcrest.version} + test + + + + + guava + + + src/main/resources + true + + + + + + + 24.0-jre + 3.5 + 4.1 + + + 3.6.1 + 2.0.0.0 + + + \ No newline at end of file diff --git a/guava-collections/src/main/resources/logback.xml b/guava-collections/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/guava-collections/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/guava/src/test/java/org/baeldung/guava/EvictingQueueUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/EvictingQueueUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/EvictingQueueUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/EvictingQueueUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaCollectionsExamplesUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionsExamplesUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaCollectionsExamplesUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionsExamplesUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaFilterTransformCollectionsUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaFilterTransformCollectionsUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaFilterTransformCollectionsUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaFilterTransformCollectionsUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMapFromSet.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSet.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaMapFromSet.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSet.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMultiMapUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaMultiMapUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaMultiMapUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaMultiMapUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaOrderingExamplesUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaOrderingExamplesUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaOrderingExamplesUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaOrderingExamplesUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaOrderingUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaOrderingUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaOrderingUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaOrderingUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaRangeMapUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaRangeMapUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaRangeMapUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaRangeMapUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/MinMaxPriorityQueueUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/MinMaxPriorityQueueUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/MinMaxPriorityQueueUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/MinMaxPriorityQueueUnitTest.java diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java b/guava-collections/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java rename to guava-collections/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java diff --git a/guava/src/test/java/org/baeldung/java/CollectionApachePartitionUnitTest.java b/guava-collections/src/test/java/org/baeldung/java/CollectionApachePartitionUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/java/CollectionApachePartitionUnitTest.java rename to guava-collections/src/test/java/org/baeldung/java/CollectionApachePartitionUnitTest.java diff --git a/guava/src/test/java/org/baeldung/java/CollectionGuavaPartitionUnitTest.java b/guava-collections/src/test/java/org/baeldung/java/CollectionGuavaPartitionUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/java/CollectionGuavaPartitionUnitTest.java rename to guava-collections/src/test/java/org/baeldung/java/CollectionGuavaPartitionUnitTest.java diff --git a/guava/src/test/java/org/baeldung/java/CollectionJavaPartitionUnitTest.java b/guava-collections/src/test/java/org/baeldung/java/CollectionJavaPartitionUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/java/CollectionJavaPartitionUnitTest.java rename to guava-collections/src/test/java/org/baeldung/java/CollectionJavaPartitionUnitTest.java diff --git a/guava-collections/src/test/resources/.gitignore b/guava-collections/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/guava-collections/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/guava-collections/src/test/resources/test.out b/guava-collections/src/test/resources/test.out new file mode 100644 index 0000000000..7a79da3803 --- /dev/null +++ b/guava-collections/src/test/resources/test.out @@ -0,0 +1 @@ +John Jane Adam Tom \ No newline at end of file diff --git a/guava-collections/src/test/resources/test1.in b/guava-collections/src/test/resources/test1.in new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/guava-collections/src/test/resources/test1.in @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/guava-collections/src/test/resources/test1_1.in b/guava-collections/src/test/resources/test1_1.in new file mode 100644 index 0000000000..8318c86b35 --- /dev/null +++ b/guava-collections/src/test/resources/test1_1.in @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/guava-collections/src/test/resources/test2.in b/guava-collections/src/test/resources/test2.in new file mode 100644 index 0000000000..622efea9e6 --- /dev/null +++ b/guava-collections/src/test/resources/test2.in @@ -0,0 +1,4 @@ +John +Jane +Adam +Tom \ No newline at end of file diff --git a/guava-collections/src/test/resources/test_copy.in b/guava-collections/src/test/resources/test_copy.in new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/guava-collections/src/test/resources/test_copy.in @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/guava-collections/src/test/resources/test_le.txt b/guava-collections/src/test/resources/test_le.txt new file mode 100644 index 0000000000..f7cc484bf4 Binary files /dev/null and b/guava-collections/src/test/resources/test_le.txt differ diff --git a/guava/README.md b/guava/README.md index fe1a347d72..7501bf08de 100644 --- a/guava/README.md +++ b/guava/README.md @@ -4,33 +4,19 @@ ### Relevant Articles: -- [Guava Collections Cookbook](http://www.baeldung.com/guava-collections) -- [Guava Ordering Cookbook](http://www.baeldung.com/guava-order) - [Guava Functional Cookbook](http://www.baeldung.com/guava-functions-predicates) -- [Hamcrest Collections Cookbook](http://www.baeldung.com/hamcrest-collections-arrays) -- [Partition a List in Java](http://www.baeldung.com/java-list-split) -- [Filtering and Transforming Collections in Guava](http://www.baeldung.com/guava-filter-and-transform-a-collection) -- [Guava – Join and Split Collections](http://www.baeldung.com/guava-joiner-and-splitter-tutorial) - [Guava – Write to File, Read from File](http://www.baeldung.com/guava-write-to-file-read-from-file) -- [Guava – Lists](http://www.baeldung.com/guava-lists) -- [Guava – Sets](http://www.baeldung.com/guava-sets) -- [Guava – Maps](http://www.baeldung.com/guava-maps) - [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial) - [Guide to Guava’s Ordering](http://www.baeldung.com/guava-ordering) - [Guide to Guava’s PreConditions](http://www.baeldung.com/guava-preconditions) - [Introduction to Guava CacheLoader](http://www.baeldung.com/guava-cacheloader) - [Introduction to Guava Memoizer](http://www.baeldung.com/guava-memoizer) - [Guide to Guava’s EventBus](http://www.baeldung.com/guava-eventbus) -- [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap) -- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) -- [Guide to Guava RangeMap](http://www.baeldung.com/guava-rangemap) - [Guide to Guava Table](http://www.baeldung.com/guava-table) - [Guide to Guava’s Reflection Utilities](http://www.baeldung.com/guava-reflection) - [Guide to Guava ClassToInstanceMap](http://www.baeldung.com/guava-class-to-instance-map) -- [Guide to Guava MinMaxPriorityQueue and EvictingQueue](http://www.baeldung.com/guava-minmax-priority-queue-and-evicting-queue) - [Guide to Mathematical Utilities in Guava](http://www.baeldung.com/guava-math) - [Bloom Filter in Java using Guava](http://www.baeldung.com/guava-bloom-filter) - [Using Guava CountingOutputStream](http://www.baeldung.com/guava-counting-outputstream) - [Hamcrest Text Matchers](http://www.baeldung.com/hamcrest-text-matchers) - [Quick Guide to the Guava RateLimiter](http://www.baeldung.com/guava-rate-limiter) -- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) diff --git a/guava/pom.xml b/guava/pom.xml index 60678608dd..1d37a79ab6 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -14,12 +14,6 @@ - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - org.apache.commons commons-lang3 @@ -56,7 +50,6 @@ 24.0-jre 3.5 - 4.1 3.6.1 diff --git a/javaxval/README.md b/javaxval/README.md index 3153546c7d..3a975022ad 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -9,3 +9,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Java Bean Validation Basics](http://www.baeldung.com/javax-validation) - [Validating Container Elements with Bean Validation 2.0](http://www.baeldung.com/bean-validation-container-elements) - [Method Constraints with Bean Validation 2.0](http://www.baeldung.com/javax-validation-method-constraints) +- [Difference Between @NotNull, @NotEmpty, and @NotBlank Constraints in Bean Validation](https://www.baeldung.com/java-bean-validation-not-null-empty-blank) diff --git a/parent-boot-1/pom.xml b/parent-boot-1/pom.xml index 7742841d07..d220b4a6b7 100644 --- a/parent-boot-1/pom.xml +++ b/parent-boot-1/pom.xml @@ -17,7 +17,7 @@ org.springframework.boot spring-boot-dependencies - 1.5.15.RELEASE + 1.5.16.RELEASE pom import diff --git a/pom.xml b/pom.xml index da1733d2b2..beb10b3287 100644 --- a/pom.xml +++ b/pom.xml @@ -378,6 +378,7 @@ google-web-toolkit gson guava + guava-collections guava-modules/guava-18 guava-modules/guava-19 guava-modules/guava-21 @@ -1285,6 +1286,7 @@ google-cloud gson guava + guava-collections guava-modules/guava-18 guava-modules/guava-19 guava-modules/guava-21