0

I am having trouble finding the most and least common name in an ArrayList. The formula should go through a file of names and count how many common names there are in the list then print the least and most common of them. I already have the most ArrayList Part finished, it is just finding the most and least common name I am having trouble with.I have no idea how to even start it.I have tried to look online but couldn't find any. I kind of tried to figure it out but this is all I could think of is using .equals.

for (int i = 0; i< dogs.size(); i++)
if dogs.get(0).getName().equals dogs.get(i).getName();
{

}
AstroCB
  • 12,337
  • 20
  • 57
  • 73
  • You can use `java.util.Map` impl for this e.g. `java.util.HashMap` –  Sep 11 '14 at 05:52
  • http://stackoverflow.com/questions/14260134/elegant-way-of-counting-occurrences-in-a-java-collection – Jason Sep 11 '14 at 06:10

2 Answers2

1
  • Create a Map<String, Integer>.
  • Loop through your ArrayList, check the Map to see if it contains the name, if it does, increment the value and put it back in the Map, it not, create a new entry and put that in.

This will give you list of the names and the number of times they appear. Run through this list (Map) and check which one has the lowest count, tracking the name as you go...

For example...

List<Dog> dogs = new ArrayList<>(25);
Map<String, Integer> dogNames = new HashMap<>(25);
for (Dog dog : dogs) {
    Integer value = dogNames.get(dog);
    if (value == null) {
        value = 0;
    }
    value++;
    dogNames.put(dog.getName(), value);
}

int leastCommon = Integer.MAX_VALUE;
String leastCommonName = null;
for (String name : dogNames.keySet()) {
    int value = dogNames.get(name);
    if (value < leastCommon) {
        leastCommon = value;
        leastCommonName = name;
    }
}

System.out.println("Least common (" + leastCommon + ") is " + leastCommonName);
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • @Bohemian Not sure you could. There's too much repeated data. We're also talking about trying to match duplicate entries. Thought about a sort, thought about `Set`, thought about a `TreeMap`. – MadProgrammer Sep 11 '14 at 06:14
1

Use a Map to collect the data, then use the Collections API to find the minimum:

List<Dog> dogs; // populate
Map<String, Integer> counts = new HashMap<>();
for (Dog dog : dogs) {
    Integer count = counts.get(dog.getName());
    counts.put(dog.getName(), count == null ? 1 : count + 1);
}

List<Map.Entry<String, Integer>> entries = new ArrayList<>(counts.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
    public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
        return Integer.compare(o2.getValue(), o1.getValue()); // Note reverse order
    }
});
String leastCommonName = entries.get(0).getKey();
int leastCommonFrequency = entries.get(0).getValue();

Here's a java 8 version of finding the least-used name:

Map.Entry<String, Integer> min = counts.entrySet().stream()
    .min((o1, o2) -> Integer.compare(o1.getValue(), o2.getValue())).get();

String leastCommonName = min.getKey();
int leastCommonFrequency = min.getValue();

Essentially list creation and sort is avoided, replaced with a one-liner that finds the minimum value from a stream (of Entries) using the same comparator, but as a lambda expression.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • That's an interesting approach, once I rinse my eyeballs out and try reading it again, I'm sure I'll figure out what it's doing ;). I guess the core difference would be in how unsorted the original list was... – MadProgrammer Sep 11 '14 at 06:44
  • @MadProgrammer yeah, I know what you mean about the eyeballs. This is not a performance thing - it's supposed to be "elegant", but frankly I was disappointed (as usual) with java's verbose syntax. The idea is there, but it's scarcely less code than your old school approach. I'll have to come back and see what it looks like using java8's closures. – Bohemian Sep 11 '14 at 07:55
  • I like the approach, I just took me a little to my head around it. Not use to seeing Map.Entry – MadProgrammer Sep 11 '14 at 07:57
  • @MadProgrammer for comparison I've posted a java 8 impl of how to find the least used dog name – Bohemian Sep 16 '14 at 07:18
  • While I'm not a fan of lambda expressions, that certainly looks less cluttered, nice example – MadProgrammer Sep 16 '14 at 07:20