简体   繁体   中英

Java arraylist find missing fields using streams

I have this below code. Two sets of arraylist. How do I use streams to iterate and compare itemlist_a and itemlist_b to detect that c and d is missing in itemlist_b? Of course I can use the traditional for loop, but is there a different way to achieve using streams or something else?

import java.util.ArrayList;
import java.util.List;

    class item {
        String name;

    public item(String name) {
        this.name = name;
    }
}

public class Test {
    public static void main(String[] args) {
        List<item> itemlist_a = new ArrayList<item>();
        itemlist_a.add(new item("a"));
        itemlist_a.add(new item("b"));

        List<item> itemlist_b = new ArrayList<item>();
        itemlist_b.add(new item("a"));
        itemlist_b.add(new item("b"));
        itemlist_b.add(new item("c"));
        itemlist_b.add(new item("d"));
    }
}

I don't think this is a good application for streams, but you could do it like this:

itemlist_a.stream().filter(e -> !itemlist_b.contains(e)).collect(Collectors.toList());

This will give you a list of all items which are in itemlist_a but not in itemlist_b. However streams are designed for functional programming which means that they should not rely on variables outside the stream. In this case itemlist_b is not in the stream but does influence the outcome of the function. It will work however.

The simplest approach is to override equals and hashCode in Item, then use removeAll on the superset to retain the difference:

//the Item class
@Override
public int hashCode() {
    // TODO
    return Objects.hashCode(name);
}

@Override
public boolean equals(Object obj) {
    // TODO: implement
    return this.name.equals(((item) obj).name);
}

Then you can get the difference:

itemlist_b.removeAll(itemlist_a);

What will be left in itemlist_b after that call will be the difference. If you want itemlist_b to be unchanged, you can do the same thing using a copy

List<Item> diff = new ArrayList<>(itemlist_b);
diff.removeAll(itemlist_a);

And you have the difference in diff .


Since you're using lists, you just need to pay attention to your business logic with respect to duplicates. removeAll will remove all matching elements.

Java List API
copy of one list and then remove all the elements common with the other

List<Item> differences = new ArrayList<>(itemlist_b);
differences.removeAll(itemlist_a);

Streams API

List<Item> differences = itemlist_b.stream()
            .filter(element -> !itemlist_a.contains(element))
            .collect(Collectors.toList());

Google Guava

List<Item> differences = new ArrayList<>(Sets.difference(Sets.newHashSet(itemlist_a), Sets.newHashSet(itemlist_b)));

Apache Commons Collections

List<Item> differences = new ArrayList<>((CollectionUtils.removeAll(itemlist_b, itemlist_a)));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM