Java Arraylist - copy one to another without duplicates

I have an ArrayList :

 Arraylist<Person> list1 = new ArrayList<Person>(); list1.add(new Person("John", 0)); list1.add(new Person("Kane", 0)); list1.add(new Person("Jen", 0)); 

And another ArrayList :

 Arraylist<Person> list2 = new ArrayList<Person>(); list2.add(new Person("John", 2)); list2.add(new Person("Kane", 4)); 

I want the resulting ArrayList contain:

 ("John", 2) ("Kane", 4) ("Jen", 0) 

I want to combine these two lists and delete the ones that have the value 0. If I did list2.addAll(list1) , then list2 has two entries for "John" with values ​​2 and 0. I want to delete the entry with the value 0 from this list.

+4
source share
9 answers

It looks like you want the maximum value for each user:

 List<Person> all = new ArrayList<Person>(); all.addAll(list1); all.addAll(list2); Map<String, Person> map = new HashMap<String, Person>(); for (Person p : all) { if (!map.containsKey(p.name) || map.get(p.name).num < p.num) { map.put(p.name, p); } } List<Person> merged = new ArrayList<Person>(map.values()); 
+2
source

Um it sounds like in your program logic, creating

 new Person("John", 2) 

not what you want - is the "new man" really called John? or is it the same old John who has a new account? You might need a feature to update points for individuals, such as

 Person.setValue(int) 

Sorry if this does not really answer your question, but it is very important to verify that you have the correct types of data structures.

+8
source

Is order important? If not, then Set makes more sense than List . Set historically been underused with programmers thinking in terms of arrays.

If the order is not important, a rather hacky approach would be to use a TreeSet with a custom comparator. Alternatively use Map<String,Person> (possibly a LinkedHashMap ).

+2
source

It seems to me that you really need a map. Create one of them and for each Person in any list, put the value 0 in the card with the person’s name as the key. Now, for each Person in each list, get the value for the person’s name from the card, add the person’s value to it and save the result back to the card. Now, if you really need this in an ArrayList, you just need to extract the key-value pairs from the map into a new list.

+2
source

Create a comparator that compares them only by name (if you don't have equals () yet).

Order lists in decreasing order of value of a person (considering the value positive.)?

Then create a set based on this comparator. Now you can call addAll.

+1
source

In your example, it looks like a map from name to any number means a more suitable data structure. With these cards, you simply do:

 map1.putAll(map2); 

If you do not want the second card to win, but a record with a higher value, you will need to do something like:

 for (Map.Entry<String, Integer> e : map2.entrySet()) { Integer v = map1.get(e.getKey()); if (v == null || v < e.getValue()) { map1.put(e.getKey(), e.getValue()); } } 
+1
source

How about this?

In the Person class:

 @Override public boolean equals(Object obj) { Person o = (Person) obj; if (o.getNombre().equals(this.nombre)) { return true; } return false; } 

then

  list2.addAll(list1); final ArrayList<Person> list3 = list2; CollectionUtils.filter(list2, new Predicate() { public boolean evaluate(Object arg0) { if (((Person) arg0).getId() == 0 && CollectionUtils.cardinality(arg0, list3) > 1) { return false; } else { return true; } } }); 
+1
source

What about...

 ArrayList<Person> list3 = new ArrayList<Person>(); list3.addAll( list1 ); list3.addAll( list2 ); System.out.println( "BEFORE" ); for ( Person person : list3 ) System.out.println( person.getName() + " = " + person.getIntParam() ); filterPeople( list3 ); System.out.println( "AFTER" ); for ( Person person : list3 ) System.out.println( person.getName() + " = " + person.getIntParam() ); 

Filter method:

 public static void filterPeople( List<Person> people ) { for ( int i = 0 ; i < people.size(); i++ ) { Person person = people.get( i ); if ( person.getIntParam() == 0 ) people.remove( i-- ); } } 
0
source

Using a card sounds like your best bet; dialing will work too. bMake sure Person provides the correct equals and hashCode values.

0
source

All Articles