TookTheRook
TookTheRook

Reputation: 827

Removing Specific Entries from ArrayList

I have an array list with the following sample entries (Name & Disease):

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

Now, for some reason, .equals isn't working. So I can't simply do if (arrayList.get(i).equals(arrayList.get(j)) then remove. So I'm comparing names and diseases individually, using compareTo for comparing the diseases (which is working).

Here is what I tried:

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

Using the above, I can find the double copy elements but I cannot separate the single instance elements. Please help! I cannot use libraries external to Java.

Here's what the above ArrayList should look like when it works:

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

Upvotes: 1

Views: 233

Answers (4)

Perception
Perception

Reputation: 80603

I assume you can use additional libraries, this solution is based on that. Pull in Guava and make use of a 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));
    }
}

Code needs cleanup, and can be optimized, but you get the gist.

On a side note, you should definitely follow better naming standards and use proper accessor/mutators for your Java objects.

New side note: next time, please indicate if the question is related to an assignment or homework. Giving near complete solutions in such cases does not help you in the long run


If you cannot pull in other libraries for any reason, you can accomplish the task in the same way, by replacing the multimap with a map/list combo:

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

Upvotes: 2

sanbhat
sanbhat

Reputation: 17622

This can be done using Map<String, Set<String>>. Please have a look at this approach.

Basically, I am maintaining a Set<String> to hold the diseases. If a name has same disease, then the Set should have a single value, and if a name has multiple, then the Set should have multiple entries.

I am eliminating the value where Set has multiple entries

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

}

And here's the output

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

Upvotes: 3

Deepak Bala
Deepak Bala

Reputation: 11185

You could do this easily with a Map<String,IdenPerson>. Override the equals() and hashCode() of IdenPerson to return true when the name and disease are the same. Before inserting an entry with put('name',person), check for the entry with get('name'). Depending on the match, do the following.

Same Name, Different Disease -> Remove Both!

If it matches an entry, check the disease and remove the entry if necessary. The person equals() match will return true if both the name and the disease are the same.

One Instance -> Keep Same Name

That should be simple too. If there is one instance of the name, a get() will not find the key ever.

Same Name, Same Disease -> Keep, but only one copy!

A get will match an existing entry but the disease will be the same and equals() will return true, so no action is necessary. Keep the existing entry and move on.

Upvotes: 1

BobTheBuilder
BobTheBuilder

Reputation: 19284

Pseodo code:

Add found boolean. Initialize it to false and if you find duplicate, set it to true. Then - at the end of the loop check if found is false. If so - add it as it a unique name.

Upvotes: 0

Related Questions