A program and test to merge two lists whose length and item values are in the range 1 to 10,000 inclusive

import org.testng.annotations.DataProvider;  
 import org.testng.annotations.Test;  
 import java.util.*;  
 import java.util.concurrent.ConcurrentHashMap;  
 import java.util.concurrent.ThreadLocalRandom;  
 import java.util.stream.Collectors;  
 import java.util.stream.Stream;  
 import static org.testng.Assert.assertEquals;  
 import static org.testng.Assert.assertTrue;  
 public class MergerTest {  
   private static final int MIN = 1;  
   private static final int MAX = 10000;  
   @DataProvider(parallel = true)  
   public Object[][] data() {  
     int[] one = new int[]{1, 2, 3, 4, 10, 20, 30};  
     int[] two = new int[]{20, 30, 1, 2, 1, 3, 4, 4, 5};  
     int[] dynamicOne = ThreadLocalRandom  
         .current().ints(MIN, MAX + 1).limit(MAX).toArray();  
     int[] dynamicTwo = ThreadLocalRandom  
         .current().ints(MIN, MAX + 1).limit(MAX).toArray();  
     int[] sameOne = new int[]{7, 7, 7, 7, 7, 7, 7};  
     int[] diffOne = new int[]{1, 2, 3, 4, 5, 6, 7};  
     int[] minOne = new int[]{MIN, MIN, MIN, MIN, MIN};  
     int[] maxOne = new int[]{MAX, MAX, MAX, MAX, MAX, MAX, MAX};  
     int[] minMax = ThreadLocalRandom  
         .current().ints(MIN, MIN + 1).limit(MAX).toArray();  
     int[] maxMax = ThreadLocalRandom  
         .current().ints(MAX, MAX + 1).limit(MAX).toArray();  
     return new Object[][]{  
         {one, two},  
         {dynamicOne, dynamicTwo},  
         {dynamicOne, dynamicOne},  
         {sameOne, sameOne},  
         {diffOne, diffOne},  
         {minOne, minOne},  
         {maxOne, maxOne},  
         {minMax, minMax},  
         {maxMax, maxMax},  
         {minMax, maxMax}  
     };  
   }  
   @Test(invocationCount = 100, dataProvider = "data")  
   public void testMergeCounter(int[] one, int[] two) {  
     Map<Integer, Long> actualMap = new Merger().mergeCounter(one, two);  
     printMap("Actual Map", actualMap);  
     List<Integer> oneList = convertToList(one);  
     List<Integer> twoList = convertToList(two);  
     Collections.sort(oneList);  
     Collections.sort(twoList);  
     Map<Integer, Long> expectedMap = computeExpectedMap(oneList, twoList);  
     printMap("Expected Map", expectedMap);  
     assertEquals(expectedMap.size(), actualMap.size());  
     assertEquals(expectedMap, actualMap);  
     assertTrue(expectedMap.equals(actualMap));  
   }  
   @DataProvider(parallel = true)  
   public Object[][] outOfRangeGreater() {  
     int[] negDynamicOne = ThreadLocalRandom  
         .current().ints(MIN - MAX, 0).limit(MAX + 1).toArray();  
     int[] negDynamicTwo = ThreadLocalRandom  
         .current().ints(MIN - MAX, 0).limit(MAX + MAX).toArray();  
     return new Object[][]{  
         {negDynamicOne, negDynamicTwo}  
     };  
   }  
   @Test(invocationCount = 100, dataProvider = "outOfRangeGreater", expectedExceptions = {RuntimeException.class},  
       expectedExceptionsMessageRegExp = "Array length should not be greater than : " + MAX)  
   public void testMergeCounterOutOfRangeGreater(int[] one, int[] two) {  
     testMergeCounter(one, two);  
   }  
   @DataProvider  
   public Object[][] outOfRangeLesser() {  
     int[] negDynamicOne = {};  
     int[] negDynamicTwo = {};  
     return new Object[][]{  
         {negDynamicOne, negDynamicTwo}  
     };  
   }  
   @Test(invocationCount = 100, dataProvider = "outOfRangeLesser", expectedExceptions = {RuntimeException.class},  
       expectedExceptionsMessageRegExp = "Array length should not be lesser than : " + MIN)  
   public void testMergeCounterOutOfRangeLesser(int[] one, int[] two) {  
     testMergeCounter(one, two);  
   }  
   @DataProvider  
   public Object[][] nullSize() {  
     return new Object[][]{  
         {null, null}  
     };  
   }  
   @Test(invocationCount = 100, dataProvider = "nullSize", expectedExceptions = {NullPointerException.class})  
   public void testMergeCounterNullSize(int[] one, int[] two) {  
     testMergeCounter(one, two);  
   }  
   private List<Integer> convertToList(int[] data) {  
     Objects.requireNonNull(data);  
     List<Integer> listData = Arrays.stream(data).boxed().collect(Collectors.toList());  
     if (listData.size() != data.length) {  
       throw new RuntimeException("Issue in converting array to list, size is different!");  
     }  
     return listData;  
   }  
   private Map<Integer, Long> computeExpectedMap(List<Integer> one, List<Integer> two) {  
     List<Integer> combinedList = Stream.concat(one.stream(), two.stream())  
         .parallel().sorted().collect(Collectors.toList());  
     if (combinedList.size() != (one.size() + two.size())) {  
       throw new RuntimeException("combined list size is wrong!");  
     }  
     return incrementCount(combinedList);  
   }  
   private void printMap(String name, Map<Integer, Long> map) {  
     System.out.println("\n" + name);  
     System.out.println("Number : Count\n===============");  
     System.out.print("{");  
     map.forEach((k, v) -> System.out.print(k + " : " + v + ", "));  
     System.out.println("}");  
   }  
   private Map<Integer, Long> incrementCount(List<Integer> data) {  
     Map<Integer, Long> counterMap = new ConcurrentHashMap<>();  
     for (int item : data) {  
       counterMap.computeIfPresent(item, (key, value) -> value + 1);  
       counterMap.putIfAbsent(item, 1L);  
     }  
     return counterMap;  
   }  
 }  


import java.util.Arrays;  
 import java.util.List;  
 import java.util.Map;  
 import java.util.Objects;  
 import java.util.concurrent.ConcurrentHashMap;  
 import java.util.function.Function;  
 import java.util.stream.Collectors;  
 public class Merger {  
   private static final int MIN = 1;  
   private static final int MAX = 10000;  
   public Map<Integer, Long> mergeCounter(int[] one, int[] two) {  
     List<Integer> oneList = convertToList(one);  
     List<Integer> twoList = convertToList(two);  
     checkLength(oneList);  
     checkLength(twoList);  
     checkRange(oneList);  
     checkRange(twoList);  
     Map<Integer, Long> counterMap = oneList.parallelStream().sorted().collect(  
         Collectors.groupingBy(  
             Function.identity(), ConcurrentHashMap::new, Collectors.counting()  
         )  
     );  
     twoList.parallelStream().sorted().forEach(item -> {  
       counterMap.computeIfPresent(item, (key, value) -> value + 1);  
       counterMap.putIfAbsent(item, 1L);  
     });  
     return counterMap;  
   }  
   private List<Integer> convertToList(int[] data) {  
     Objects.requireNonNull(data);  
     return Arrays.stream(data).boxed().collect(Collectors.toList());  
   }  
   private void checkRange(List<Integer> data) {  
     if (!data.stream().allMatch(i -> i >= MIN && i <= MAX)) {  
       throw new RuntimeException("Array content should be in range of : " + MIN + " and : " + MAX);  
     }  
   }  
   private void checkLength(List<Integer> data) {  
     if (data.size() != Math.min(data.size(), MAX)) {  
       throw new RuntimeException("Array length should not be greater than : " + MAX);  
     }  
     if (data.size() != Math.max(data.size(), MIN)) {  
       throw new RuntimeException("Array length should not be lesser than : " + MIN);  
     }  
   }  
 }  

Comments

Popular posts from this blog

FileSystemUtils

TakeScreenshotAspect

GemfireConfig