Friday 21 February 2020

Check two lists contain same elements or not (order not required)

By default 'equals' method of List return true, if other list contain exactly same elements in the same order.


As you see above diagram, all the lists list1, list2 and list3 contain same elements but list1 and list2 contain the elements in same order. So as per equals method list1 and list2 are equal but not list1 and list3.

App.java
package com.sample.app;

import java.util.Arrays;
import java.util.List;

public class App {

 public static void main(String[] args) {
  List<String> list1 = Arrays.asList("Hello", "How", "Are", "You");
  List<String> list2 = Arrays.asList("How", "You", "Hello", "Are");
  List<String> list3 = Arrays.asList("Hello", "How", "Are", "You");

  System.out.println("list1.equals(list2) : " + list1.equals(list2));
  System.out.println("list1.equals(list3) : " + list1.equals(list3));

 }

}

Output
list1.equals(list2) : false
list1.equals(list3) : true

Now our problem is to check whether two lists contain same elements or not, order doesn’t matter here.

Approach 1: Sort the lists and call equals method.
public static <T extends Comparable<T>> boolean isListsEquals_Approach1(List<T> list1, List<T> list2) {

 if ((list1 == null && list2 != null) || (list1 != null && list2 == null)) {
  return false;
 }

 if ((list1 == null && list2 == null) || (list1.isEmpty() && list2.isEmpty())) {
  return true;
 }

 if (list1.size() != list2.size()) {
  return false;
 }

 Collections.sort(list1);
 Collections.sort(list2);

 return list1.equals(list2);

}

Approach 2: Using a counter map.
First traverse through first list and maintain a counter for number of occurrences of every object in the list. Next traverse through second list and decreases the counter for every object occurrence. At last the count for all the objects in the map must be 0.
public static <T extends Comparable<T>> boolean isListsEquals_Approach2(List<T> list1, List<T> list2) {

 if ((list1 == null && list2 != null) || (list1 != null && list2 == null)) {
  return false;
 }

 if ((list1 == null && list2 == null) || (list1.isEmpty() && list2.isEmpty())) {
  return true;
 }

 if (list1.size() != list2.size()) {
  return false;
 }

 Map<T, Integer> counterMap = new HashMap<>();

 for (T ele : list1) {
  Integer currentCount = counterMap.get(ele);

  if (currentCount == null) {
   counterMap.put(ele, 1);
  } else {
   counterMap.put(ele, currentCount + 1);
  }
 }

 for (T ele : list2) {
  Integer currentCount = counterMap.get(ele);

  if (currentCount == null) {
   return false;
  } else {
   counterMap.put(ele, currentCount - 1);
  }

 }

 for (Integer count : counterMap.values()) {
  if (count != 0) {
   return false;
  }
 }

 return true;

}


Find the below working application.

ListUtil.java
package com.smaple.app.utils;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ListUtil {
 public static <T extends Comparable<T>> boolean isListsEquals_Approach1(List<T> list1, List<T> list2) {

  if ((list1 == null && list2 != null) || (list1 != null && list2 == null)) {
   return false;
  }

  if ((list1 == null && list2 == null) || (list1.isEmpty() && list2.isEmpty())) {
   return true;
  }

  if (list1.size() != list2.size()) {
   return false;
  }

  Collections.sort(list1);
  Collections.sort(list2);

  return list1.equals(list2);

 }

 public static <T extends Comparable<T>> boolean isListsEquals_Approach2(List<T> list1, List<T> list2) {

  if ((list1 == null && list2 != null) || (list1 != null && list2 == null)) {
   return false;
  }

  if ((list1 == null && list2 == null) || (list1.isEmpty() && list2.isEmpty())) {
   return true;
  }

  if (list1.size() != list2.size()) {
   return false;
  }

  Map<T, Integer> counterMap = new HashMap<>();

  for (T ele : list1) {
   Integer currentCount = counterMap.get(ele);

   if (currentCount == null) {
    counterMap.put(ele, 1);
   } else {
    counterMap.put(ele, currentCount + 1);
   }
  }

  for (T ele : list2) {
   Integer currentCount = counterMap.get(ele);

   if (currentCount == null) {
    return false;
   } else {
    counterMap.put(ele, currentCount - 1);
   }

  }

  for (Integer count : counterMap.values()) {
   if (count != 0) {
    return false;
   }
  }

  return true;

 }
} 

ListUtilTest.java

package com.sample.app.utils;

import org.junit.Test;

import static com.smaple.app.utils.ListUtil.isListsEquals_Approach1;
import static com.smaple.app.utils.ListUtil.isListsEquals_Approach2;
import static org.junit.Assert.*;

import java.util.*;

public class ListUtilTest {

 @Test
 public void nullCheck1() {
  assertTrue(isListsEquals_Approach1(null, null));
  assertTrue(isListsEquals_Approach2(null, null));
 }

 @Test
 public void nullCheck2() {
  assertFalse(isListsEquals_Approach1(null, Collections.emptyList()));
  assertFalse(isListsEquals_Approach2(null, Collections.emptyList()));
 }

 @Test
 public void emptyList1() {
  assertTrue(isListsEquals_Approach1(Collections.emptyList(), Collections.emptyList()));
  assertTrue(isListsEquals_Approach2(Collections.emptyList(), Collections.emptyList()));
 }

 @Test
 public void emptyList2() {
  assertFalse(isListsEquals_Approach1(Collections.emptyList(), null));
  assertFalse(isListsEquals_Approach2(Collections.emptyList(), null));
 }

 @Test
 public void sameElements_approach1() {
  List<String> list1 = Arrays.asList("Hello", "How", "Are", "You");
  List<String> list2 = Arrays.asList("How", "You", "Hello", "Are");
  List<String> list3 = Arrays.asList("Hello", "How", "Are", "You");

  assertTrue(isListsEquals_Approach1(list1, list2));
  assertTrue(isListsEquals_Approach1(list1, list3));
 }

 @Test
 public void diffNoOfElements_approach1() {
  List<String> list1 = Arrays.asList("Hello", "How", "Are", "You", "Hello");
  List<String> list2 = Arrays.asList("How", "You", "Hello", "Are");
  List<String> list3 = Arrays.asList("Hello", "How", "Are", "You", "How");

  assertFalse(isListsEquals_Approach1(list1, list2));
  assertFalse(isListsEquals_Approach1(list1, list3));
 }

 @Test
 public void duplicateElements_approach1() {
  assertTrue(isListsEquals_Approach1(Arrays.asList("A", "A", "B"), Arrays.asList("B", "A", "A")));
  assertFalse(isListsEquals_Approach1(Arrays.asList("A", "A", "B"), Arrays.asList("B", "A", "B")));
  assertFalse(isListsEquals_Approach1(Arrays.asList("A", "A", "B"), null));
 }

 @Test
 public void sameElements_approach2() {
  List<String> list1 = Arrays.asList("Hello", "How", "Are", "You");
  List<String> list2 = Arrays.asList("How", "You", "Hello", "Are");
  List<String> list3 = Arrays.asList("Hello", "How", "Are", "You");

  assertTrue(isListsEquals_Approach2(list1, list2));
  assertTrue(isListsEquals_Approach2(list1, list3));
 }

 @Test
 public void diffNoOfElements_approach2() {
  List<String> list1 = Arrays.asList("Hello", "How", "Are", "You", "Hello");
  List<String> list2 = Arrays.asList("How", "You", "Hello", "Are");
  List<String> list3 = Arrays.asList("Hello", "How", "Are", "You", "How");

  assertFalse(isListsEquals_Approach2(list1, list2));
  assertFalse(isListsEquals_Approach2(list1, list3));
 }

 @Test
 public void duplicateElements_approach2() {
  assertTrue(isListsEquals_Approach2(Arrays.asList("A", "A", "B"), Arrays.asList("B", "A", "A")));
  assertTrue(isListsEquals_Approach2(Arrays.asList("A", "A", "B", null, null),
    Arrays.asList(null, null, "B", "A", "A")));
  assertFalse(isListsEquals_Approach2(Arrays.asList("A", "A", "B"), Arrays.asList("B", "A", "B")));
  assertFalse(isListsEquals_Approach2(Arrays.asList("A", "A", "B"), null));
 }
} 


You may like

No comments:

Post a Comment