Definity
Definity

Reputation: 722

For loop confusion, why isn't this looping?

So I have a method in which I pass an ArrayList to the idea of this method is to take the input and split each set of matching strings into their own separate list. Here some pseudo code.

Array = (a,a,a,b,c,d,d,e,e,e,e,e,f,f,s)

So what I want this algo to do is to split this array into a 2D array with equal elements. Like this.

A[0][] = (a,a,a)
A[1][] = (b)
A[2][] = (c)
A[3][] = (d,d)
A[4][] = (e,e,e,e,e)
A[5][] = (f,f)
A[6][] = (s)

So what I tried to do is put it in a for loop that check an extra element ahead to see if it NOT equal to, then it knows t

 int equalStringGroupIndex = 0;
    int i = 0;

    for(int first = 0, second = 0 ; input.get(first).equals(input.get(second)); second++){
        equalStringGroups[equalStringGroupIndex][i] = input.get(second);
        i++;
        //This if statment checks the element ahead then equals first = second, But when it jumps back to the top of the loop in the debugger it does'nt seem to check it even though in my Watches it's True
        if(!input.get(first).equals(input.get(second + 1))){
            equalStringGroupIndex++;
            i = 0;
            first = second;
        }
    }

Why does it not loop after adding the first set of 'a' to the 2D array Thanks.

UPDATE: Thanks for the help, I decided to go the HashMap route. Here's what I came up with. It appear's to work.

private HashMap<String, Integer> countDuplicates(ArrayList<String> input){

    HashMap<String, Integer> duplicates = new HashMap<>();

    //Value init loop, sets all values to 0;
    for (String s : input){
        Integer valueInitVar = 0;
        duplicates.put(s, valueInitVar);
    }

    //Increases the value by 1  each time the same key is encountered;
    for (String s : input){
        Integer tempDuplicateAmount = duplicates.get(s);
        //I could use the '++' operator but I feel ' var += 1' is much nicer to read;
        tempDuplicateAmount += 1;
        duplicates.put(s, tempDuplicateAmount);
    }

    return duplicates;
}

Upvotes: 1

Views: 101

Answers (2)

GhostCat
GhostCat

Reputation: 140427

I suggest something else:

List<List<Whatever>> splitSame(List<Whatever> input) {
  List<List<Whatever>> rv = new ArrayList<>();
  List<Whatever> currentValues = new ArrayList<>(); 
  Whatever lastChecked = input.get(0);
  for (Whatever what : input) {
    if (lastChecked.equals(what)) {
      currentValues.add(what);
    } else {
      rv.put(currentValues);
      currentValues = new ArrayList<>();
    }
    lastChecked = what;
  }
  rv.put(currentValues);
  return rv;

The point is: you can easily walk over you one input list to collect equal objects within sub lists. And in the end, you just pull those together.

I am sure some java8 guru could rewrite the above using streams into something even more concise and less complicated.

No need for additional two-dim arrays complexity here at all!

( hint: code just written down, might contain typos, and there is a subtle bug in there when the last element is different, but: it is meant to give you an idea how to do things differently; further details left to the reader )

Upvotes: 1

Hypnic Jerk
Hypnic Jerk

Reputation: 1192

If you are going to stick to doing it this way, I suggest changing your conditional in the for loop to be second < input.size (or length)

int equalStringGroupIndex = 0;
int i = 0;

for(int first = 0, second = 0 ; second < input.size(); second++){
    equalStringGroups[equalStringGroupIndex][i] = input.get(second);
    i++;

    if(!input.get(first).equals(input.get(second + 1))){
        equalStringGroupIndex++;
        i = 0;
        first = second+1;
    }
}

This way, you are looping ONLY through the array, no out of bounds exceptions there.

I also changed your first = second to first = second+1 because once you have found they are not equal, you should set the first index to the the next one and by doing first = second you are not.

Upvotes: 0

Related Questions