user3400060
user3400060

Reputation: 309

Filter ArrayList according to a criteria

I have a requirement to write a method that filters an ArrayList between a minimum and maximum range.So the method accepts a List,int min and an integer max. Here is the method I wrote.

public static List<Integer> filterRange(final List<Integer> l3,int min,int max)
{
    System.out.println(l3);
    Iterator<Integer> iter = l3.iterator();
    while (iter.hasNext()) {
        int i=iter.next();
        if (i<=max && i>=min) {
            iter.remove();
        }
    }
    System.out.println(l3);
    return l3;

}

However, this would not do the desired function. A suggestion on this would be nice.

Thanks

Upvotes: 0

Views: 1077

Answers (3)

deanosaur
deanosaur

Reputation: 611

Here's a more generic version of the filterRange function. It takes as params:

  • a list of comparable objects List<T> where <T extends Comparable<T>>
  • a high value object T
  • a low value object T

It returns the same list but with any objects outside of the min/max range removed.

The function iterates through the list of T's and uses the Comparable interface method compareTo() to compare each T in the list to the high and low values. If the item falls in range, it add the item to the new list.

public static <T extends Comparable<T>> List<T> filterRange(List<T> list, T low, T high){
    List<T> newlist = new ArrayList<T>();
    for(T t:list) {
        if(t.compareTo(low)>=0 && t.compareTo(high)<=0) {
            newlist.add(t);
        }
    }
    return list;
}

I tested it with this code

String[] array = new String[]{"apple", "banana", "cherry", 
                              "grape", "kiwi", "lemon", 
                              "lime", "orange", "pear", 
                              "plum", "strawberry"};
  List<String> strings = Arrays.asList(array);
  List<String> array1 = filterRange(strings,"c","h");

and got:

cherry
grape

Upvotes: 1

Alexis C.
Alexis C.

Reputation: 93842

You need to get each element and then test it. Currently you're calling next() twice in a row. So if you have a List that contains (1,2,3,4) and you're starting the first iteration, this line:

if (iter.next().intValue()<=6 && iter.next().intValue()>=2)

is equivalent to:

if (1<=6 && 2>=2)

To avoid that store the element and then perform your tests.

 while (iter.hasNext()) {
        Integer i = iter.next();
        if (i.intValue()<=6 && i.intValue()>=2) {
            iter.remove();
        }
    }

Note that you are not using your min and max parameters values. Also I don't know why you made your method generic.


After your edit, far away from the original post, the problem is that you call next() without knowing if your list contains some elements and even if it has, it would loop infinitely since you're not calling next() inside your loop (because hasNext() will always return true). So it should be:

  while (iter.hasNext()) {
        int i=iter.next();
        if (i<=6 && i>=2) {
            iter.remove();
        }
    }

Be aware that your list can contains null elements, so this line int i=iter.next(); could throw a NPE when trying to unbox the value in the Integer object.

Finally if you're using (again be aware of null elements) you could do:

l.removeIf(i -> i >= min && i <= max);

Upvotes: 1

FazoM
FazoM

Reputation: 4956

You cant use next() function twice like that. It gets next element each time. Try storing return from next() in a local variable before comparing to min / max.

Upvotes: 0

Related Questions