user3235881
user3235881

Reputation: 487

Compare two array lists in java

I have two different arrays oldUsers and newUsers containing instances of the class User. User contain firstname, lastname and age attributes. I want to know the number of oldUsers objects in the newUsers array that have the same attributes. Shall I use two for loops and compare the arrays one per one or is there a function that can do the same work ?

Upvotes: 0

Views: 97

Answers (3)

Aaron
Aaron

Reputation: 24802

Assuming your User objects correctly implement equals() and hashCode(), I would use one of the lists' retainAll(Collection other) method to craft the intersection of both lists and then return its size.

Upvotes: 2

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48600

You first need to override equals() and hashCode(). Then you can implement an intersection() method.

Number of identical values: 2
------------------------------
- { 'firstname': 'Bob', 'lastname': 'Smith', 'age': 30 }
- { 'firstname': 'Robert', 'lastname': 'Brown', 'age': 51 }

Main

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<User> oldUsers = new ArrayList<User>();
        List<User> newUsers = new ArrayList<User>();
        List<User> intersect;

        oldUsers.addAll(Arrays.asList(
            new User("Bob", "Smith", 30),
            new User("Tom", "Jones", 42),
            new User("Robert", "Brown", 51),
            new User("James", "Jones", 28)
        ));

        newUsers.addAll(Arrays.asList(
            new User("Robert", "Brown", 51), // Same
            new User("Bob", "Smith", 30),    // Same
            new User("Tom", "Jones", 21),
            new User("James", "Hendrix", 28)
        ));

        intersect = intersection(oldUsers, newUsers);

        System.out.printf("Number of identical values: %d%n%s%n",
                intersect.size(), "------------------------------");
        for (User user : intersect) {
            System.out.printf("- %s%n", user);
        }
    }

    // http://stackoverflow.com/a/5283123/1762224
    public static <T> List<T> intersection(List<T> list1, List<T> list2) {
        List<T> list = new ArrayList<T>();
        for (T t : list1) {
            if (list2.contains(t)) {
                list.add(t);
            }
        }
        return list;
    }
}

User

public class User {
    private String firstname;
    private String lastname;
    private int age;

    public String getFirstname() { return firstname; }
    public void setFirstname(String firstname) { this.firstname = firstname; }

    public String getLastname() { return lastname; }
    public void setLastname(String lastname) { this.lastname = lastname; }

    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }

    public User(String firstname, String lastname, int age) {
        super();
        this.firstname = firstname;
        this.lastname = lastname;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((firstname == null) ? 0 : firstname.hashCode());
        result = prime * result + ((lastname == null) ? 0 : lastname.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;

        User other = (User) obj;

        if (age != other.age) return false;

        if (firstname == null) {
            if (other.firstname != null) return false;
        } else if (!firstname.equals(other.firstname)) return false;

        if (lastname == null) {
            if (other.lastname != null) return false;
        } else if (!lastname.equals(other.lastname)) return false;

        return true;
    }

    @Override
    public String toString() {
        return String.format("{ 'firstname': '%s', 'lastname': '%s', 'age': %d }",
                firstname, lastname, age);
    }
}

Alternative Methods

Set :: Retain All

public static <T> List<T> intersection(List<T> list1, List<T> list2) {
    Set<T> set = new HashSet<T>(list1);
    set.retainAll(new HashSet<T>(list2));
    return new ArrayList<T>(set);
}

List :: Java 8 Filter Stream

public static <T> List<T> intersection(Collection<T> list1, Collection<T> list2) {
    return list1.stream().filter(item -> list2.contains(item)).collect(Collectors.toList()); 
}

Upvotes: 2

Adnan Isajbegovic
Adnan Isajbegovic

Reputation: 2297

If you have equals() and hashCode() implemented correctly, you can place all inputs from oldUsers array to Set and then check data from newUsers if they are in that Set or not. This will work in O(max(n, m)) (place data in Set is O(n), check newUsers if they are in Set is O(m), so you have O(n) + O(m) = O(max(n,m)), where n is size of oldUsers list and m is size of newUsers list).

For example:

    private int numberOfSameUsers(ArrayList<User> oldUsers, ArrayList<User> newUsers) {
        Set<User> oldUsersSet = new HashSet<>(oldUsers);
        int counter = 0;
        for (int i = 0; i < newUsers.size(); i++) if (oldUsersSet.contains(newUsers.get(i))) counter++;
        return counter;
    }

Upvotes: 0

Related Questions