2

First time here so I hope this makes sense!

I have two object arrays say l1 and l2, I want to run a compare between these two lists and get a the unmatched value in say in l3. User class contains 2 Strings:

userEnteredValue 
valueReturnedFromDatabase

Say, l1 contains: Java, JSF, JAXR, foo l2 contains: JSF, JAXR

I could run a compare for matching values, but for not for non-matching values. The logic seems to be flawed. Any help?

For matching values:

for(User u1 : l1) {
   for(User u2: l2) { 
      if(u1.getUserEnteredValue().equals(u2.getValueReturnedFromDatabase())) {
        l3.add(u1);
      }
} 

But, for the non-matching when I say not equal to, instead of getting only the unique values I get all values. A couple of similar posts on Stackoverflow suggest to implement the equals and hashcode method in the User class. Is this necessary, since my arraylist size don't go beyond 5 to 10.

1
  • Can't you use 2 HashSets for this and find the overlapping parts using that? Commented May 18, 2016 at 6:10

7 Answers 7

3

You can do something like this:

for(User u1 : l1) {
    boolean unique = true;
    for(User u2: l2) { 
        if(u1.getUserEnteredValue().equals(u2.getValueReturnedFromDatabase())) {
            unique = false;
            break;
        }
    } 
    if(unique){
        l3.add(u1);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Cheers! I used this snippet, and it works like a charm.
2

You can use the contains() method from java.util.ArrayList to determine whether your list contains the object.

Example:

for(User u1:l1) {
    if(!l2.contains(u1)) {
        l3.add(u1);
    }
}

1 Comment

l2.contains(u1) is not the same as u1.getUserEnteredValue().equals(u2.getValueReturnedFromDatabase()) he will need to override equals and hashCode in the User class in order for that to be true.
2

https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#contains(java.lang.Object)

Iterate through one array and check if it "contains()" the element from other array, using the above method provided with ArrayList in java.

Comments

2

If you can use Java 8 and you would like some shorter format:

 List<String> l1 = Arrays.asList("a", "b", "c");
 List<String> l2 = Arrays.asList("b");

 List<String> l3 = l1.stream().filter(e -> !l2.contains(e)).collect(Collectors.toList());

Comments

1

Let's make your problem even smaller.
I have 2 arrays
l1 = [1, 2]
l2 = [2, 3]

for(int i : l1) {
    for(int j : l2) {
        if(i != j) {
            l3.add(i);
        }
    }
}

Now let's examine this code.
When i = 1, j = 2 then i != j i.e. 1 != 2 is true and 1 will be inserted in l3.
When i = 1, j = 3 then i != j i.e. 1 != 3 is true and 1 again will be inserted in l3.
When i = 2, j = 2 then i != j i.e. 2 != 2 is false
When i = 2, j = 3 then i != j i.e. 1 != 2 is true and 2 will be inserted in l3.
So the final array will be l3 = [1, 2] (if it is a set. or [1, 1, 2] if it is a list) i.e. all the elements of l1 will be inserted in l2.

To get unique elements of l1 you will have to check all elements of l2 for same element in l1 1 by 1 and if it is not found in complete l2 then add it in l3.

rootloop:
for(int i : l1) {
    for(int j : l2) {
        if(i == j) {
            continue rootloop;
        }
        l3.add(i);
    }
}

Now change the above code to work for your problem.

But these kind of searching are so common that their implementation is already given in collection framework.

for(int i : l1) {
    if(!l2.contains(i)){
        l3.add(i);
    }
}

1 Comment

Thank you for the explanation. It would have good if I had put a couple of console messages and traced the snippet. Hope this would help someone else.
1

One could use the Array of matching entities for the creation of unmatched entities as follows:

User[] matchingUsers = ...
User[] AllUsers = ...

List<User> listOfMatchingUsers = Arrays.asList(matchingUsers);
List<User> listOfAllUsers = Arrays.asList(allUsers);

List<User> unmatchedUsers = listOfAllUsers.removeAll(listOfMatchingUsers);

Comments

1

I see many answers using list.contains, i do not agree as contains use direct loop so the performance will be an issue for large lists O(n^2).

Instead you can use maps, add each list to a map with key and value the same then do the following:

Iterator it = map1.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry pair = (Map.Entry)it.next();
    if(map2.get(pair.getValue())!=null) {
            list3.add(map2.get(pair.getValue()));
     }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.