2

I have seen the answer a here and I am not sure it answers my issue. So I have an arraylist of Float type containing a bunch of numbers. I wish to remove all the numbers which are 30 more or less than the previous value. So, I am comparing 'n' and 'n+1' and removing 'n+1' if (n+1)>(30+n) and vice versa. I have written the following code but my solution isn't working.

for(int i = 0; i<hr_list.size()-1; i++)
    {
        Float x= hr_list.get(i);
        Float y = hr_list.get(i+1);

        if(y>(x+30.0f)||y<(x+30.0f))
        {
            hr_list.remove(i+1);
        }
    }
Community
  • 1
  • 1
Santu Reddy
  • 87
  • 1
  • 9
  • 1
    Perhaps you meant `if(y>(x+30.0f)||y<(x-30.0f))`. Though it's not clear what you want to do if the list is 10 50 90. Do you remove just the 50, or should the 90 also be removed? – Eran Apr 07 '16 at 06:04
  • Thing is, I am storing heart rate values and if the HR(n+1) is 30+HR, I am removing it since it is probably not the correct value. In your example, 50 and 90 would be removed for instance since my baseline there is 10. – Santu Reddy Apr 07 '16 at 06:07
  • In that case, follow advise by @Eran, but also do `i--` inside the `if` statement (after the `remove()`), to prevent advancing on this iteration, where you remove the following element. – Andreas Apr 07 '16 at 06:09
  • OKay, what about this one? http://stackoverflow.com/questions/1196586/calling-remove-in-foreach-loop-in-java/1196612#1196612 It says I have to use an 'iterator'. But in this case my for-loop is itself iterating, isn't it? – Santu Reddy Apr 07 '16 at 06:13

3 Answers3

1

Based on your comment, I'd do something like this :

for(int i = 0; i<hr_list.size()-1; i++)
{
    Float x= hr_list.get(i);
    Float y = hr_list.get(i+1);

    if(y>(x+30.0f)||y<(x-30.0f))
    {
        hr_list.remove(i+1);
        i--; // you want to compare the current i'th element against the
             // new (i+1)'th element in the next iteration
    }
}

Of course, if the baseline (first element) itself is wrong, this will fail. For example, if you have a list containing 20 70 76 79 89 70, this loop will leave you with just the 20, which doesn't look like a good behavior. Perhaps you should calculate the average and remove elements which are far from the average.

Eran
  • 387,369
  • 54
  • 702
  • 768
0

You cannot modify a list which you are currently iterating on (which totally makes sense).

The proper approach is to build a list where you only keep the values matching the condition

public List<Integer> filterList(List<Integer> list) {
    List<Integer> result = new ArrayList<Integer>();
    if (list.size() == 0) return l;
    int current = l.get(0);
    boolean filtered = false;
    for (int v : l) {
        if (Math.abs(v - current) < 30) {
            result.add(v);
        } else {                 //
            filtered = true;     //
        }
        current = v;            //
    }
    if (filtered) return result;
    else return l;
}

You might want to make recursive calls in order to have a final list matching the initial condition (recursive stop condition : myList.equals(filterList(myList)), or just remove the lines ending with '//' in the code sample

Ji aSH
  • 3,206
  • 1
  • 10
  • 18
0

Please see the below code

for(int i=1;i<list.size();i++){
    float c=list.get(i);
    float p=list.get(i-1);
    if( (Math.abs(c-p)>30)
        list.remove(i);
}
Gyanendra Dwivedi
  • 5,511
  • 2
  • 27
  • 53