2010-12-19 4 views
0

Tout d'abord, je m'excuse d'avoir posté une question similaire à "4462626". Je veux comparer à deux objets (qui sont la relation parent-enfant). Comment pensez-vous du code suivant. Je pense que ce n'est pas efficace car trop de boucles existent. Pouvez-vous me conseiller? (Remarque: Je ne suis pas autorisé à modifier Item.class et ItemEx.class doit étendre Item.class)Comment afficher si une collection a été ajoutée ou supprimée?

EXPECTED RESULT 
------------------------ 
add:4 
delete:2 
------------------------ 

package com.javastudy; 

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

public class CollectionCompareToObjectsForLoop { 

public static void main(String[] args) { 

    List<Item> beforeList = new ArrayList<Item>(); 
    List<ItemEx> afterList = new ArrayList<ItemEx>(); 

    beforeList.add(new Item(1L)); 
    beforeList.add(new Item(2L)); // delete 
    beforeList.add(new Item(3L)); 

    afterList.add(new ItemEx(1L)); 
    afterList.add(new ItemEx(3L)); 
    afterList.add(new ItemEx(4L)); // added 

    // Check Add 
    List<Item> addList = new ArrayList<Item>(); 
    for(Item afterItem : afterList){ 
    if(checkAdd(afterItem, beforeList)){ 
    addList.add(afterItem); 
    } 
    } 

    // Check Delete 
    List<Item> deleteList = new ArrayList<Item>(); 
    for(Item beforeItem : beforeList){ 
    if(checkDelete(beforeItem, afterList)){ 
    deleteList.add(beforeItem); 
    } 
    } 

    // Print Result 
    for(Item item : addList){ 
    System.out.println("add:" + item.getId()); 
    } 
    for(Item item : deleteList){ 
    System.out.println("delete:" + item.getId()); 
    } 

} 

private static boolean checkAdd(Item afterItem, List<Item> beforeList) { 
    for(Item beforeItem : beforeList){ 
    if (afterItem.getId().equals(beforeItem.getId())){ 
    return false; 
    } 
    } 
    return true; 
} 

private static boolean checkDelete(Item beforeItem, List<ItemEx> afterList) { 
    for(Item afterItem : afterList){ 
    if (beforeItem.getId().equals(afterItem.getId())){ 
    return false; 
    } 
    } 
    return true; 
} 

} 

package com.javastudy; 

public class Item { 

private Long id; 

public Item(Long id) { 
    this.id = id; 
} 

public Long getId() { 
    return id; 
} 

public void setId(Long id) { 
    this.id = id; 
} 

} 

package com.javastudy; 

public class ItemEx extends Item { 

private String name; 

public ItemEx(Long id) { 
    super(id); 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

} 

Répondre

0

Je suppose que les Id s que vous avez donnés aux articles sont en réalité des ID, de sorte que les articles ayant le même ID sont considérés égaux et qu'il n'y a qu'un seul article par ID. Ensuite, vous pouvez utiliser le code suivant:

package so4483619; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.LinkedHashMap; 
import java.util.List; 
import java.util.Map; 

public class AddDel { 

    private static <K, V> HashMap<K, V> newLinkedHashMap() { 
    return new LinkedHashMap<K, V>(); 
    } 

    private static <K, V> HashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> other) { 
    return new LinkedHashMap<K, V>(other); 
    } 

    private static void computeDeleteAndAdd(List<? extends Item> before, List<? extends Item> after) { 
    Map<Long, Item> beforeById = newLinkedHashMap(); 
    for (Item item : before) { 
     beforeById.put(item.getId(), item); 
    } 

    Map<Long, Item> afterById = newLinkedHashMap(); 
    for (Item item : after) { 
     afterById.put(item.getId(), item); 
    } 

    Map<Long, Item> onlyBefore = newLinkedHashMap(beforeById); 
    onlyBefore.keySet().removeAll(afterById.keySet()); 

    Map<Long, Item> onlyAfter = newLinkedHashMap(afterById); 
    onlyAfter.keySet().removeAll(beforeById.keySet()); 

    for (Map.Entry<Long, Item> entry : onlyBefore.entrySet()) { 
     System.out.println("delete:" + entry.getKey()); 
    } 
    for (Map.Entry<Long, Item> entry : onlyAfter.entrySet()) { 
     System.out.println("add:" + entry.getKey()); 
    } 
    } 

    public static void main(String[] args) { 
    List<Item> beforeList = new ArrayList<Item>(); 
    List<ItemEx> afterList = new ArrayList<ItemEx>(); 

    beforeList.add(new Item(1L)); 
    beforeList.add(new Item(2L)); // delete 
    beforeList.add(new Item(3L)); 

    afterList.add(new ItemEx(1L)); 
    afterList.add(new ItemEx(3L)); 
    afterList.add(new ItemEx(4L)); 

    computeDeleteAndAdd(beforeList, afterList); 
    } 
} 

Quelques remarques:

  • Les LinkedHashMap se comporte comme une carte, mais se rappelle l'ordre dans lequel les éléments ont été insérés. Ceci permet de rendre la sortie prévisible et d'avoir le même ordre que dans les beforeList et afterList.
  • Vos cours Item et ItemEx ne sont pas les méthodes equals(Object) et hashCode(), donc ils ne peuvent pas être utilisés directement en tant que clés dans un HashMap. C'est mon hypothèse que vous considérez deux Item avec le même ID pour être égal.
  • Les deux méthodes d'assistance newLinkedHashMap juste sauvegarder quelques touches dans la méthode computeDeleteAndAdd. Sans ces méthodes, vous devrez dire new LinkedHashMap<Long, Item>(...) au lieu d'un simple newLinkedHashMap(...).
0

Cette solution perd l'ordre des listes ...

Set<Item> added = new HashSet<Item>(afterList); 
Set<Item> removed = new HashSet<Item>(beforeList); 
added.removeAll(beforeList); 
removed.removeAll(afterList); 
for(Item item : added){ 
    System.out.println("add:" + item.getId()); 
} 
for(Item item : removed){ 
    System.out.println("delete:" + item.getId()); 
} 
+1

Assurez-vous que 'Item' écrase' equals' et 'hashCode'. – finnw

+0

@finnw: excellent point. J'aurais dû ajouter cette hypothèse. –

Questions connexes