Compact ways to filter even numbers in Java int array I am writing some examples of Java programs on GitHub rsp/ppj for people to learn and I want them to be as simple and compact as possible, to work on Java 1.7.x (a.k.a. Java 7) and to not use any non-standard libraries that need installation.

This question is about my WhereEven example:

a function of an int[] array that returns an int[] array with only even numbers

(The method can internally use any other data types if it makes sense.)

Here is how my example looks like right now:

static int[] even(int[] t) {
    int i, j;
    for (i=j=0; i &lt; t.length; i++)
        if (t[i] % 2 == 0) j++;
    int[] r = new int[j];
    for (i=j=0; i &lt; t.length; i++)
        if (t[i] % 2 == 0) r[j++] = t[i];
    return r;
}


I am not satisfied with that code because it is much more complex than the same in JavaScript - even using the old ES5 syntax (few years older than Java 7) it is:

function even(t) {
    return t.filter(function(x){ return x % 2 == 0; });
}


It is even better in Scheme, which is amazing considering the fact that this is a language that's 40 years old:

(define (even t)
    (filter even? t))


But I can't get to the solution that is even remotely as simple and readable in Java. Of course I can add comments and more meaningful variable names, but the point is that in Scheme and JS the code is simple and the meaning is obvious as it is. What I am looking for is a way to write a better code, not to write the same code but with better names.

What in your opinion is "the best" way to improve the above code to be most useful for an educational example like this? Maybe the shortest way in terms of lines/characters, the most readable way, the most idiomatic way, the way using best practices, the most crazy way? I am looking forward to every suggestion of my code improvement that would help people learn something about Java and maybe I'll put few different approaches in my tutorial.

The only requirement is taking an int[] array, returning a new int[] array (but internally the method can use any other data types if it makes sense), working on Java 1.7.x (a.k.a. Java 7) and not using any non-standard classes.
First... choose the right problem or choose what you want them to learn

Let me first question your assumptions (pure Java 7, no "extra" libraries and array filtering). I do so under the premise that you want your students not just learn "pure Java 7" (ain't best idea neither commercially nor academically, nor will it make them greater programmers).

Also, why I keep typing "extra libraries" in "":


most of the projects now have Guava or Apache Commons
new Java has lambdas (for a reason and due to serious demand)
there are at least 2 popular libraries that enable Java 7 to use FP-like programming style: Javaslang, Lambda4Java (IIRC)


This is not "for fun", but because there was need for it. Among mainstream languages none treat "backward compatibility" so seriously as Java does. Despite deprecating APIs since version 1.1, they have yet to cut a thing. This means, there's lots of OLD stuff there.

Also, the problem you have (filtering data) is VERY FP friendly. FP languages among first operations have map and filter. Java at it's inception targeted C++ people, who wrote programs iteratively (for loops, step-by-step instructions to solve problems). FP works on streams and pipelines (data flows, and while it does, we do things).

So, yes, Scheme (FP language) is awesome for your problem. So is anything that has decent FP features (JS can be argued so).

Pure Java, without Apache Commons, Javaslang, Lambdas etc. will be hard-pressed for it:


you want to filter data
you want to use arrays (in Java objects are central concept, arrays are closer to primitives)
in Java, Collections are arrays equivalents of objects


Summarizing this long intro:

Filtering is FP-concept, FP-friendly languages or strict FP languages are  therefore better. If you choose examples like that and want to work with Java, work with Java Collections, libraries geared towards filtering/collections/data pipelines and Java 8 that introduces Lambdas.  

Java 8 and streams

First proposition for you, uses streams, introduced in Java 8. There's a library that tries to make lambdas (and perhaps streams?) available in Java 7, so you may be able to show same code with it.

static void java8even(int[] t) {
    IntStream iWantEvens = IntStream.of(t);

    iWantEvens
        .filter(i -&gt; i % 2 == 0)
        .forEach(new IntConsumer() {
            @Override
            public void accept(int value) {
                System.out.println(value);
            }
        });
}


I build a java.util.Stream with Stream.of(input array). Then I filter the stream and using forEach I on the fly create an IntConsumer that just prints the value. forEach performs an action that you define on every stream element. I could've used toArray and then function would - instead of having side effect - return an array, which I'd then have to print in main, iterating over it. It might look simpler and be 1-2 lines terser, but it's less memory efficient.

Answer within all your limits

With all that said, Java 7, no "extra" libs:

/**
 * Created by LAFK on 17.11.15.
 */
public class EvenFilter {

    static ArrayList evens = new ArrayList();

    public static void main(String[] args) {
        int[] simpleTable = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        for (int i: simpleTable) {
            if (i%2 == 0) {
                evens.add(i);
            }
        }
        System.out.println(evens);
    }
}


I used ArrayList without any type-safety. I then iterated over input array and added elements meeting criteria to ArrayList. Then, I printed out ("returned") ArrayList.

Why?


Java ain't that great with arrays (try printing an array without iterating over it's elements, weak API, fixed length of an array, while Java Lists can grow and shrink over time)
even more so with primitives, like int, try getting that into collections!
Java API for collections ain't that great as well, compared to modern languages or FP ones, but it's better than what you can do with just array 
I don't need the fixed size with lists


I think similar thing can be done with a StringBuffer and were you to process something more text-oriented, that would be better choice.