Understanding lambda expressions
I'm not entirely sure if I understand the Lambda Expressions tutorial in the Oracle Java tutorials. The main thing that confuses me is the lambda index parameter. ds.print(index ->{...}
How does the compiler know what an index of values ββis? The index is not declared anywhere in the program, so what exactly is the Index parameter even referring to and how does the compiler know?
The question arises:
public class DataStructure {
private final static int SIZE = 15;
private int[] arrayOfInts = new int[SIZE];
public DataStructure() {
for (int i = 0; i < SIZE; i++) {
arrayOfInts[i] = i;
}
}
public int size() {
return SIZE;
}
public int get(int index) {
return arrayOfInts[index];
}
interface DataStructureIterator extends java.util.Iterator<Integer> { }
private class EvenIterator implements DataStructureIterator {
private int nextIndex = 0;
public boolean hasNext() {
return (nextIndex <= SIZE - 1);
}
public Integer next() {
Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]);
nextIndex += 2;
return retValue;
}
}
public DataStructureIterator getEvenIterator() {
return new EvenIterator();
}
public void printEven() {
DataStructureIterator iterator = getEvenIterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
public void print(DataStructureIterator iterator) {
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
public void print(java.util.function.Function<Integer, Boolean> function) {
for (int i = 0; i < SIZE; i++) {
if (function.apply(i)) {
System.out.print(arrayOfInts[i] + " ");
}
}
System.out.println();
}
public static Boolean isEvenIndex(Integer index) {
if (index % 2 == 0) return Boolean.TRUE;
return Boolean.FALSE;
}
public static Boolean isOddIndex(Integer index) {
if (index % 2 == 0) return Boolean.FALSE;
return Boolean.TRUE;
}
public static void main(String s[]) {
DataStructure ds = new DataStructure();
System.out.println("printEven()");
ds.printEven();
System.out.println("print(DataStructureIterator) with "
+ "getEvenIterator");
ds.print(ds.getEvenIterator());
System.out.println("print(DataStructureIterator) with "
+ "anonymous class, odd indicies");
ds.print(
new DataStructure.DataStructureIterator() {
private int nextIndex = 1;
public boolean hasNext() {
return (nextIndex <= ds.size() - 1);
}
public Integer next() {
int retValue = ds.get(nextIndex);
nextIndex += 2;
return retValue;
}
}
);
System.out.println("print(Function) with lambda expressions");
ds.print(index -> {
if (index % 2 == 0) return Boolean.TRUE;
return Boolean.FALSE;
});
ds.print(index -> {
if (index % 2 == 0) return Boolean.FALSE;
return Boolean.TRUE;
});
System.out.println("print(Function) with method references");
ds.print(DataStructure::isEvenIndex);
ds.print(DataStructure::isOddIndex);
}
}
source to share
The method ds.print
takes a type argument Function<Integer,Boolean>
. So:
ds.print(index -> {
if (index % 2 == 0) return Boolean.TRUE;
return Boolean.FALSE;
});
behaves equivalently to this syntax, using an anonymous class instead of a lambda:
ds.print(new Function<Integer,Boolean>() {
@Override
public Boolean apply(Integer index) {
if (index % 2 == 0) return Boolean.TRUE;
return Boolean.FALSE;
}
});
(Functional method of the class Function
apply
.)
Thus, the parameter name index
is arbitrary. You can call it what you want. It's just a name that's local to your lambda method. Its value is provided by this call to print
:
if (function.apply(i)) ...
source to share