2013-04-09 28 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,因此不需要采取任何措施。保留现有条目并继续。