1

I'm writing a method that allows me to count how many times an element of type String shows up in a LinkedList of type Strings. my code shown below does not work. I keep getting index out of bounds in the line i commented on down below. Can't seem to find the bug

public int findDuplicate (LinkedList<String> e) {
int j = 1;
LinkedList<String> test = e;
while (!test.isEmpty()){
    test = e;
    String value = test.pop();
    //Screws up here when i = 6 
    for(int i =0; i<=test.size() && test.get(i)!=null; i++){ 
        String value3 = test.get(i);
        if(e.get(i).equals(value) && i<=test.size()){
            String value2 = test.get(i); 
            j++;
            String Duplicate = e.get(i);
            e.remove(i);
        }
    }
    System.out.println(value + " is listed " + j + " times");

}
return j;
}

using hashmaps.. still doesn't work

public void findDuplicate (LinkedList e) {

    Map<String,Integer> counts = new HashMap<String,Integer>();

    while(!e.isEmpty()){
        String value = e.pop();
        for(int i =0; i<e.size(); i++){
            counts.put(value, i);
        }
    }
    System.out.println(counts.toString());
}

My code should go through the linked list find out how many times an element within the list appears and deletes duplicates from the list at the same time. Then prints the element and the number of times it appears in the list. I posted about this last night but didn't get a response yet. Sorry for the repost.

Ali
  • 157
  • 1
  • 4
  • 15

5 Answers5

6

You are running off the end of the list. Change

for(int i =0; i<=test.size() && test.get(i)!=null; i++){ 

to

for(int i =0; i< test.size() && test.get(i)!=null; i++){ 

Valid indexes for a List (or an array) are 0 through size() - 1.

rgettman
  • 176,041
  • 30
  • 275
  • 357
2

Regarding your hashmap example to count the duplicates:

@Test
public void countOccurrences() {
    LinkedList<String> strings = new LinkedList<String>(){{
        add("Fred");
        add("Fred");
        add("Joe");
        add("Mary");
        add("Mary");
        add("Mary");
    }};

    Map<String,Integer> count = count(strings,new HashMap<String,Integer>());
    System.out.println("count = " + count);
}

private Map<String, Integer> count(List<String> strings, Map<String, Integer> runningCount) {
    if(strings.isEmpty()) {
        return runningCount;
    }
    String current = strings.get(0);
    int startingSize = strings.size();
    while(strings.contains(current)) {
        strings.remove(current);
    }
    runningCount.put(current, startingSize - strings.size());
    return count(strings,runningCount);
}

If you want the original strings list preserved you could do

    Map<String,Integer> count = count(new LinkedList<String>(strings),new HashMap<String,Integer>());
    System.out.println("strings = " + strings);
    System.out.println("count = " + count);
Mike Hogan
  • 9,933
  • 9
  • 41
  • 71
2

Check out google's guava collections which has a perfect class for maintaining a map and getting a count:

https://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap

Multiset<String> wordsMultiset = HashMultiset.create();
wordsMultiset.addAll(words);
// now we can use wordsMultiset.count(String) to find the count of a word
bsautner
  • 4,479
  • 1
  • 36
  • 50
1

This doesn't affect your out of bounds issue, but you are removing elements from your list while still evaluating it. If you remove an element, you should call i-- afterwards, or you skip the next entity (which is re-indexed) for evaluation.

Also of note regarding your code, I see you are trying to make a copy of your list, but standard assignment means test and e both point to the same instance. You need to use Collections.copy() see this SO thread on how to use the class.

Community
  • 1
  • 1
JoshDM
  • 4,939
  • 7
  • 43
  • 72
1

I hope you realize what the test = e statement is doing. After this statement executes both test and e refer to the same object.

If anyone of them modifies the list, the other sees it as they both are looking at the same object.

If this is not intended you need to clone the list before assigning it to another list reference.