2013-04-09 51 views
1

具體條目我有下面的示例條目(名稱&病)一個數組列表:去除ArrayList中

1. Name: Aimee Cholmondeley. Disease: German measles 
2. Name: Colin Anissina.  Disease: Diphtheria 
3. Name: Colin Anissina.  Disease: Malaria 
4. Name: Aimee Cholmondeley. Disease: Typhoid fever 
5. Name: Isaias Cheung.  Disease: Haemophilus Influenza 
6. Name: Isaias Cheung.  Disease: Scarlet fever 
7. Name: Sebastian Cutting. Disease: Gingivitis 
8. Name: Juan Weiss.   Disease: Acquired Immunodeficiency Sydrome (AIDS) 
9. Name: Kaelyn Nauman.  Disease: Amebiasis 
10. Name: Kaelyn Nauman.  Disease: Human Pulmonary Syndrome (HPS) 
11. Name: Lyndsey Stapleton. Disease: Chlamydia 
12. Name: Lyndsey Stapleton. Disease: Chlamydia 
  • 相同的名稱,不同的疾病 - >刪除這兩個!
  • 一個實例 - >保持
  • 同一個名字,同病 - >保持,但只有一個副本!

現在,由於某種原因,.equals不起作用。所以我不能簡單地做if (arrayList.get(i).equals(arrayList.get(j)) then remove。所以我比較名稱和疾病個別,使用compareTo比較疾病(這是工作)。

這裏是我的嘗試:

for (int i = 0; i < IDArray.size(); i++){ //IDArray contains all the elements 
     int countFound = 0; 
     IdenPerson curr1 = IDArray.get(i); 
     for (int j = i + 1; j < IDArray.size(); j++) { 
       IdenPerson curr2 = IDArray.get(j); 
       if (curr1.name.toString().equals(curr2.name.toString())) { //If Name is same 
        if ((curr1.dis.toString().compareTo(curr2.dis.toString())) == 0) { // And Disease is same 
         System.out.println(curr1.name.toString()); // Print that Name 
         break; 
        } 
       } 
       else { 
        // If name is not same, and only repeated once ... how to do this? 
       } 
     } 
    } 
public static class IdenPerson { 
    String name; 
    String dis; 
} 

使用上面,我可以找到雙副本元素,但我不能單一實例元素分開。請幫忙!我不能使用Java外部的庫。

這裏是上面的ArrayList應該是什麼時,它的工作原理是:

1. Name: Sebastian Cutting. Disease: Gingivitis 
2. Name: Juan Weiss.   Disease: Acquired Immunodeficiency Sydrome (AIDS) 
3. Name: Lyndsey Stapleton. Disease: Chlamydia 
+0

如果有兩個條目名稱相同,但不同的疾病,*哪個*你想被刪除? – 2013-04-09 06:19:22

+0

我想他們都被刪除或不復制到另一個ArrayList。如果它們是完全重複的,我想打印/複製其中的一個。 – TookTheRook 2013-04-09 06:20:23

+0

它看起來像名稱地圖 - >疾病(或疾病列表)會更好。 – BobTheBuilder 2013-04-09 06:21:12

回答

3

這可以使用Map<String, Set<String>>完成。請看看這種方法。

基本上,我維持Set<String>來控制疾病。如果名稱具有相同的疾病,那麼Set應具有單值,並且如果名稱具有多個,則Set應具有多個條目

消除其中設置有多個條目

public class ArrayListDisease { 

    public static List<String> process(List<String> input) { 

     Map<String, Set<String>> map = new HashMap<String, Set<String>>(); 

     for(String s : input) { 
      String [] nameAndDisease = s.split("\\."); 
      if(map.containsKey(nameAndDisease[0])) { 
       Set<String> diseases = map.get(nameAndDisease[0]); 
       diseases.add(nameAndDisease[1]); 
      } 
      else { 
       Set<String> set = new HashSet<String>(); 
       set.add(nameAndDisease[1]); 
       map.put(nameAndDisease[0], set); 
      } 
     } 

     List<String> res = new ArrayList<String>(); 
     for(Entry<String, Set<String>> e : map.entrySet()) { 
      String key = e.getKey(); 
      Set<String> values = e.getValue(); 
      if(values.size() == 1) { 
       res.add(key+"."+values.iterator().next()); 
      } 
     } 
     return res; 
    } 


    public static void main(String [] args) { 
     List<String> input = new ArrayList<String>(); 
     input.add("Name: Aimee Cholmondeley. Disease: German measles"); 
     input.add("Name: Colin Anissina.  Disease: Diphtheria"); 
     input.add("Name: Colin Anissina.  Disease: Malaria"); 
     input.add("Name: Aimee Cholmondeley. Disease: Typhoid fever"); 
     input.add("Name: Isaias Cheung.  Disease: Haemophilus Influenza"); 
     input.add("Name: Isaias Cheung.  Disease: Scarlet fever"); 
     input.add("Name: Sebastian Cutting. Disease: Gingivitis"); 
     input.add("Name: Juan Weiss.   Disease: Acquired Immunodeficiency Sydrome (AIDS)"); 
     input.add("Name: Kaelyn Nauman.  Disease: Amebiasis"); 
     input.add("Name: Kaelyn Nauman.  Disease: Human Pulmonary Syndrome (HPS)"); 
     input.add("Name: Lyndsey Stapleton. Disease: Chlamydia"); 
     input.add("Name: Lyndsey Stapleton. Disease: Chlamydia"); 

     System.out.println(process(input)); 
    } 

} 

而且這裏的值是輸出

[Name: Lyndsey Stapleton. Disease: Chlamydia, Name: Juan Weiss.   Disease: Acquired Immunodeficiency Sydrome (AIDS), Name: Sebastian Cutting. Disease: Gingivitis] 
+0

工作得很好。謝謝 :)! – TookTheRook 2013-04-09 23:40:01

2

我假設你可以使用額外的庫,這個解決方案是基於這一點。拉Guava並利用一個MultiMap的:

LinkedListMultimap<String, String> mappedPersons = LinkedListMultimap.create(); 

for (int i = 0; i < IDArray.size(); i++) { 
    IdenPerson person = IDArray.get(i); 
    mappedPersons.put(person.name, person.dis); 
} 

List<IdenPerson> uniques = new ArrayList<IdenPerson>(mappedPersons.size()); 
for(int i = 0 ; i < IDArray.size(); i++) { 
    if(mappedPersons.get(IDArray.get(i).name).size() == 1) { 
     uniques.add(IDArray.get(i)); 
    } 
} 

代碼需要清理,可以優化,但你得到的要點。

在附註上,您應該遵循更好的命名標準,併爲Java對象使用正確的訪問器/修改器。

新的一面注意:下次請說明問題是否與作業或作業有關。在這種情況下,接近完整的解決方案給予不幫你,從長遠來看


如果你不能在其他圖書館拉以任何理由,你可以以同樣的方式完成任務,用一個取代多重映射圖/表組合:

Map<String, Set<String>> mappedPersons = 
    new HashMap<String, Set<String>>(IDArray.size()); 

for (int i = 0; i < IDArray.size(); i++) { 
    IdenPerson person = IDArray.get(i); 
    List<String> diseases = mappedPersons.get(person.name); 
    if(diseases == null) { 
     diseases = new HashSet<String>(4); 
     mappedPersons.put(person.name, diseases); 
    } 

    diseases.add(person.dis); 
} 

List<IdenPerson> uniques = new ArrayList<IdenPerson>(mappedPersons.size()); 
for(int i = 0 ; i < IDArray.size(); i++) { 
    if(mappedPersons.get(IDArray.get(i).name).size() == 1) { 
     uniques.add(IDArray.get(i)); 
    } 
} 
+0

不幸的是,我不能使用外部庫。學校服務器不會支持它。 – TookTheRook 2013-04-09 06:38:34

+0

multimap不是絕對必要的。請參閱對其的替代編輯。 – Perception 2013-04-09 06:48:38

+0

如果名字相同但疾病不同,'uniques'仍然會包含條目。 OP想要刪除這些條目。你需要重複疾病或使用'Set '。 – 2013-04-09 06:53:29

0

Pseodo代碼:

添加found布爾值。將其初始化爲false,如果發現重複,請將其設置爲true。 然後 - 在循環結束時檢查是否發現錯誤。如果是這樣 - 將其添加爲唯一名稱。

1

你可以用Map<String,IdenPerson>輕鬆做到這一點。當名稱和疾病相同時,覆蓋IdenPerson的equals()和hashCode()以返回true。在插入put('name',person)的條目之前,請檢查get('name')的條目。根據匹配情況,執行以下操作。

相同的名稱,不同的疾病 - >刪除兩個!

如果它匹配一個條目,檢查疾病並在必要時刪除條目。如果名字和疾病都相同,那麼equals()匹配的人將返回true。

一個實例 - >保持相同的名稱

這應該是很簡單。如果有一個名稱的實例,get()將無法找到該鍵。

相同的名稱,相同的疾病 - >保留,但只有一個副本!

get將匹配現有條目,但疾病將是相同的並且equals()將返回true,因此不需要採取任何措施。保留現有條目並繼續。