-1

I got an ArrayList of users who can login to web site multiple times per day. How can I create an ArrayList of unique users out of the first arraylist. In other words I need to ignore multiple logins. If for example there were 20 logins to the web site and all those logins were made by two users then the second list should contain just two user objects. I am newbie to Java programming language and I need help.

Here is the User class:

public class User {

    private String id
    private String date;

    public String getId() {
        return id
    }

    public void setId(String id) {
        this.id = id
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }
}

And here is how I was going to solve the issue but for some reason it doesn't work.

ArrayList<User> userList = new ArrayList<>();
ArrayList<User> uniqueUserlist = new ArrayList<>();

    String id = null;

    for(User user : userList) {

        if (user.getId() != id) {
            uniqueUserlist.add(user);
        }

        id = user.getId();
    }

Thank you.

J-Alex
  • 6,881
  • 10
  • 46
  • 64
Daniel Foo
  • 73
  • 3
  • 9
  • You have not init data for your `userList` before using in the loop – TuyenNTA Aug 03 '17 at 22:16
  • 2
    `==` and `!=` in Java compare reference equality, not data equality. If you want to check if the ids are equal, use `user.getId().equals(id)`. – azurefrog Aug 03 '17 at 22:16
  • If you modify your `User` class to give it sensible [`equals`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-) and [`hashCode`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--) methods (and `toString` for completeness), then you can use the solution in "[Get unique values from arraylist in java](https://stackoverflow.com/questions/13429119)". – Kevin J. Chase Aug 03 '17 at 22:53

3 Answers3

3

While your bug is simply not comparing Strings correctly, there's a far better way to do this:

  • Add a hashCode and equals to your User class
  • Place these items into a LinkedHashSet

What you accomplish:

  • Defining hashCode allows you to use data structures which require a hash value, like Set.
  • LinkedHashSet preserves insertion order and eliminates duplicates at the cost of a little extra memory.
Makoto
  • 104,088
  • 27
  • 192
  • 230
  • What is the hashCode is not int? What is the hashCode is string? – Daniel Foo Aug 03 '17 at 22:29
  • @DanielFoo: `hashCode` is *always* `int`. You are calculating a value. If you're not too sure, then you can use `31 * id.hashCode() + 31 * date.hashCode()`, although be aware that I did this off the top of my head and will not vouch for its reliability whatsoever. *That* I leave as an exercise for the reader. – Makoto Aug 03 '17 at 22:31
  • In my case the user id might have letters. How do I override hashcode and equals if I am going to compare users by string id. – Daniel Foo Aug 03 '17 at 22:36
1

If you don't want duplicates but want to use an ArrayList a quick fix would be to move all the items into a HashSet (which does not allow duplicates), clear the ArrayList and then add the items from the HashSet back into the ArrayList.

-1

You can make use of Stream API....put your list in the TreeSet from which you provide a custom comparator that compares id uniquely.

Something like the below would serve your need.

ArrayList<User> uniqueUserlist = userList.stream()
                            .collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparingInt(User::getId))), ArrayList::new));
Jeeppp
  • 1,553
  • 3
  • 17
  • 39