2010-12-19 8 views
0

まず、「4462626」と同様の質問を投稿することについてお詫び申し上げます。私は2つのオブジェクト(親子関係です)と比較したいと思います。どのようにコードをフォローすると思いますか?あまりにも多くのfor-loopが存在するので効率的ではないと私は思う。私にアドバイスできますか? (注意:私はItem.classとItemEx.classはItem.classを拡張する必要があり、変更することは許されないのです)コレクションを追加または削除したかどうかを表示する方法は?

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; 
} 

} 

答えて

0

私がいると仮定しますアイテムに与えたIdは本当にIDなので、同じIDを持つアイテムは等しいとみなされ、IDごとに1つのアイテムしか存在しません。

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); 
    } 
} 

いくつかの発言:それから、次のコードを使用することができます

  • マップのようなLinkedHashMap振舞うが、要素が挿入された順番を記憶しています。これは、出力を予測可能にし、beforeListafterListと同じ順序を持つようにするためです。
  • あなたのクラスItemItemExは方法equals(Object)hashCode()を持っていないので、それらはHashMapのキーとして直接使用することはできません。これは、同じIDを持つ2つのItemが等しいとみなすという私の前提です。
  • 2つのヘルパーメソッドnewLinkedHashMapは、メソッドcomputeDeleteAndAddにいくつかのキーストロークを保存するだけです。これらの方法がなければ、newLinkedHashMap(...)の代わりにnew LinkedHashMap<Long, Item>(...)と言う必要があります。
0

このソリューションは、リストの順番を失う...

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

'Item'が' equals'と 'hashCode'をオーバーライドしていることを確認してください。 – finnw

+0

@finnw:優れた点。私はその前提を追加すべきだった。 –

関連する問題