9

I have two Pojo Classes on with different field with unique ID.

I want to perform intersection of two List<A> and List<B> .

What is best way to do. One is i can simply iterate twice and but then the complexity is too high n2.

is any better way to do that ? Can i Do it with Comparator?

Class A {
Id, Name ,DOB}

Class B{
id, aid ,location }

I have list of A , and List of B

now want to get list of A with location in B

Zuned Ahmed
  • 1,357
  • 6
  • 29
  • 56

5 Answers5

3

Apache Commons Collections has a method to do this: CollectionUtils.intersection. It doesn't use generics, however.

There is also this SO question: List intersection in java

Community
  • 1
  • 1
Paul
  • 19,704
  • 14
  • 78
  • 96
  • It's important to note that CollectionUtils.intersection makes no guarantees on the order of the items in the result (it's return type is a Collection). Since you're dealing with Lists, keep this in mind. – NBJack Jun 27 '12 at 20:54
  • If order is important, you should try ListUtils.intersection. – NBJack Jun 27 '12 at 21:11
2

Using Java 8 streams

List<A> listA = new ArrayList<A>();
List<B> listB = new ArrayList<B>();

Set<Integer> aIdsFromBList = listB.stream().map(B::getAId).collect(Collectors.toSet());

return listA.stream
    .filter(a -> aIdsFromBList.contains(a.getId()))
    .collect(Collectors.toList());
Cavyn VonDeylen
  • 4,189
  • 9
  • 37
  • 52
2

You could put elements of List<B> into a HashMap<Integer,B>, with the id being the key.

Having done that, you can iterate over elements of List<A> and quickly look up the corresponding B elements using the hash map. That'll provide the structure you require ("list of A with location in B").

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • -1 You gotta be kidding. *Really* crap solution, but if you must do it like that, use a `Set`, not a `Map` (you are only using the keyset of the map anyway - does that seem familiar.. keySET?... **SET**?) geez... – Bohemian Jan 17 '12 at 08:17
  • 1
    @Bohemian: You clearly have a different solution in mind. Why don't you go ahead and post it as an answer? – NPE Jan 17 '12 at 08:23
  • 1
    Fair challenge - I have posted a solution. It was the end of a long day - sorry for the 'tude. I could have said it nicer. It's still true however that a `Map` is the wrong tool – Bohemian Jan 17 '12 at 09:29
2
  1. Sort both the list in increasing order of Id.

  2. Start with List A, and find corresponding index in List B. Remeber current index of List B. say (indB)

  3. Start with next index of List A, and compare in List B starting from (indB+1)

  4. repeat from step 1 to 4, until either List A is ended OR List B is ended.

Azodious
  • 13,752
  • 1
  • 36
  • 71
1

Try this:

public static void main(String[] args) {System.nanoTime()
    List<A> as = new ArrayList<A>();
    List<B> bs = new ArrayList<B>();

    // Collect all A.ids in the list of B into a Set
    Set<String> baids = new HashSet<String>();
    for (B b : bs)
        baids.add(b.aid);

    // iterate through the list of A discarding those that don't have a B
    for (Iterator<A> i = as.iterator(); i.hasNext();)
        if (!baids.contains(i.next().Id)) // contains() executes fast for a Set
            i.remove();

    // now list "as" contains all A that have a B with A.Id = B.aid 
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • The required output is a *"list of A with location in B"*. How does this algorithm achieve that? – NPE Jan 17 '12 at 09:30
  • but then i m doing first for loop for get ids from one list, second for loop to get from second list and internally retain all is also doing for loop and after this i will run one more for loop for getting exact object. Is it possible that we can do using object and overriding equals? – Zuned Ahmed Jan 17 '12 at 09:42
  • @aix (thinks omg... must I spoonfeed?) Fine... I have added one more line to show how the mystery of getting a list from a set is solved. – Bohemian Jan 17 '12 at 19:15
  • It's not totally clear who needs to spoonfeed whom, but the last line of your `main()` probably won't even compile. Even if it did, you've lost all the attributes of `A`. To be totally frank, I think this debate is a waste of time for both of us. We are clearly not on the same page. – NPE Jan 17 '12 at 19:27
  • @aix yeah that code wasn't thought through by me. I've fixed it to what I consider to be a good solution. – Bohemian Jan 17 '12 at 22:33