Reputation: 827
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
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
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
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
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