6

I have a List<User> users, where classUser has one property username. I also have anotherList<User> activeUsers. Let users = activeUsers + inactiveUsers. Now I want to extract inactiveUsers from users based on username property. I solved this problem using two for-loops. I think this is not efficient way. so if anyone know how it can be done efficiently please let me know.

e.g. I have activeUsers[1,3] and users[1,2,3,4] and want to build inactiveUsers[2,4].

8
  • Are you allowed to modify the User class ? Commented Apr 14, 2013 at 13:17
  • no I don't allow to modify User class. Commented Apr 14, 2013 at 13:20
  • How do you identify who is active? Commented Apr 14, 2013 at 13:22
  • @Ray Stojonic:items in activeUsers are active. Commented Apr 14, 2013 at 13:24
  • So you have activeUsers[1,3] and users[1,2,3,4] and you want to build inactiveUsers[2,4]? Commented Apr 14, 2013 at 13:27

4 Answers 4

2

In Java, you can use the Collection interface's removeAll method.

// Create a couple ArrayList objects and populate them
// with some delicious fruits.
Collection firstList = new ArrayList() {{
    add("user1");
    add("user2");
}};

Collection secondList = new ArrayList() {{
    add("user1");
    add("user1");
    add("user3");
    add("user4");
}};

// Show the "before" lists
System.out.println("First List: " + firstList);
System.out.println("Second List: " + secondList);

// Remove all elements in firstList from secondList
secondList.removeAll(firstList);

// Show the "after" list
System.out.println("Result: " + secondList);

The above code will produce the following output:

First List: [user1, user2]
Second List: [user1, user2, user3, user4]
Result: [user3, user4]
Sign up to request clarification or add additional context in comments.

1 Comment

This solution still runs in O(n^2), OP wanted a faster solution
0

Well, based on the restriction of modifying the User class and nature of your question there is no way of doing it lesser than o(n^2) with two lists (i.e. two loops). Of course if you could have two lists of each type your problem is done.

But since you cannot than the logic is : (assuming your structures are lists only)

Iterate users list (o(n)) :
   - Search the active users list for the current user (o(n)) 

No matter how you look at it you get o(n^2)

If you could modify User to have activation property you can easily reduce the problem to o(n) by a single search

11 Comments

Nope, he could convert the List to a Set and then do the iteration, then it would only be O(n).
You did not read the answer as I said with two lists. And searching a set is not faster than searching a list. You need a hash map with a good hash function to reach o(1) searches)
Yeah, you're right. But why talk about what he can't do instead of talking about what he can do?
Because he is restricted to the given input (two lists and a User class which he cannot modify) so the answer is no you cannot do it faster than what he described
Nowhere does he state that restriction.
|
0

You could store users in a Set based on if they're active or not, I would prefer a property on User but I guess you don't want that in this assignment of yours. Using this code your problem is solved in O(n) time. Assuming you haven't messed up equals/hashCode in User.

package com.stackoverflow.q15999468;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Users
{
    public static void main(String[] args)
    {
        List<User> users = Arrays.asList(u1,u2,u3,u4,u5);
        List<User> activeUsers = Arrays.asList(u3,u5);

        Set<User> activeUsersSet = new HashSet<User>(activeUsers);

        List<User> inactiveUsers = new ArrayList<User>();

        for(User user : users)
        {
            if(!activeUsersSet.contains(user))
            {
                inactiveUsers.add(user);
            }
        }
        System.out.println("Inactive users: " + inactiveUsers);
    }
}

4 Comments

I have a list of active users so how i check equality of username?
I have a List<User> inactiveUsers how I get single username(Steve) for checking?
Perhaps I misunderstood you, I thought you were looking for whether or not a specific user is inactive. If you post your (complete) current code I'll probably understand the task better.
I have a List<User> users[u1,u2,u3,u4,u5], I have another List<User> activeUsers[u3,u5]. Now I want to get List<User> inactiveUsers[u1,u2,u4].
0

This should work

List<User> inactiveUsers = new ArrayList<User>(users);
inactiveUsers.removeAll(activeUsers) ;

2 Comments

removeAll returns boolean value.
but it should, make sure User overrides equals

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.