Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to skip particular array index when using IntStream.filter in Java 8

Tags:

java

java-8

I am learning and new to Java 8 Stream API,

I wanted to write a program to find even numbers in integer array using IntStream, so I came up with this solution,

int[] numbers = {1,2,3,4,5,6,7,8,9,10};

IntStream.of(numbers).filter(i -> i%2 == 0).forEach(System.out::println);

and this is working correctly for me.

but how can I modify the filter to skip certain array indexes from being checked from numbers ?

for example,

if i want to skip numbers[1] from being checked if it even or not then what should i do ?

because i in the filter are the values of the array elements not their indexes.

is it possible to do so ?

like image 882
Joe Avatar asked Feb 13 '15 18:02

Joe


People also ask

How do you skip values in an array?

Here is a tutorial on how you can skip on some elements of an array? Suppose we want to skip every third element. We need to store this data in an array. C++ has one keyword known as continue which skips the current iteration and continues, whenever it sees the keyword continue.

What is Skip method in Java 8?

The skip(n) method is an intermediate operation that discards the first n elements of a stream. The n parameter can't be negative, and if it's higher than the size of the stream, skip() returns an empty stream.

What is the purpose of the limit () method in Java 8?

The limit method of the Stream class introduced in Java 8 allows the developer to limit the number of elements that will be extracted from a stream. The limit method is useful in those applications where the user wishes to process only the initial elements that occur in the stream.

How do I find the index of a stream?

Create an AtomicInteger for index. Get the Stream from the array using Arrays. stream() method. Map each elements of the stream with an index associated with it using map() method where the index is fetched from the AtomicInteger by auto-incrementing index everytime with the help of getAndIncrement() method.


2 Answers

Create a stream of the array indices instead, and filter it, before mapping to the array elements:

int[] numbers = ...;
IntStream.range(0, numbers.length).filter(i -> i!=1)
    .map(i -> numbers[i]).forEach(System.out::println);

If you need first to filter some elements out by index, and some out by value, you can have one filter before the map and one after.

If you need to check both the index and the value in the same filter, then I think the best way is to create a class to hold both values:

class IndexedValue {
    private int index, value;
    IndexedValue(int index, int value) {
        this.index = index ;
        this.value = value ;
    }
    int getIndex() { return index ;}
    int getValue() { return value ;}
}

and then you can do

int[] numbers = ... ;
IntStream.range(0, numbers.length).map(i -> new IndexedValue(i, numbers[i]))
    .filter(v -> v.getIndex() == 1 || v.getValue() % 2 == 0)
    .forEach(System.out::println);
like image 86
James_D Avatar answered Sep 28 '22 18:09

James_D


A variant of @James_D's answer.

Imagine if we could avoid the usage of situational classes such as IndexedValue, because we are silly billies or something.

Well, imagine no more:

int[] numbers = ... ;
IntStream.range(0, numbers.length)
  // an anonymous class is defined at this juncture
  // for the sake of discussion, said class is named
  // Whatever (FF8 reference).
  .mapToObj(i -> new Object() {
    final int index = i;
    final int value = numbers[i];
  })
  // IntStream translated to Stream<Whatever>
  .filter(v -> v.index != 1)
  // Stream<Whatever> with non-1 indices
  .filter(v -> v.value % 2 == 0)
  // Stream<Whatever> with even values
  .mapToInt(v -> v.value)
  // Stream<Whatever> to IntStream
  .forEach(System.out::println)
;

Disclaimer: I know this because I got bored once and tried it myself. There is no guarantee that this code will work with non-JavaC compilers. (Apparently, Eclipse's type inference is not as sexy as javac's. Whatever. [FF8 reference])

like image 24
srborlongan Avatar answered Sep 28 '22 19:09

srborlongan