Ответ 1
Идея лямбда-выражений заключается в том, что вместо создания класса, реализующего функциональный интерфейс, вы можете определить лямбда-выражение типа этого интерфейса.
Например, ваш класс Merge
реализует BinaryOperator<int[]>
и может быть заменен следующим выражением лямбда:
BinaryOperator<int[]> merge = (t,u) -> {
int[] result = new int[t.length + u.length];
for (int i = 0, j = 0, k = 0; i < result.length; i++){
if( j == t.length){
result[i] = u[k++];
} else if (k == u.length) {
result[i] = t[j++];
} else {
result[i] = t[j] < u [k] ? t[j++] : u[k++];
}
}
return result;
};
Теперь мы также можем создать лямбда-выражение для замены класса MergeSort
, и, объединив два лямбда, получим:
public class MergeSortMain {
public static Function<int[], int[]> mergeSort;
public static void main(String[] args) {
int values[] = {3,12,6,7,2,1,23,4,5,7,8,4,2,5,365};
mergeSort = l -> {
BinaryOperator<int[]> merge = (t,u) -> {
int[] result = new int[t.length + u.length];
for (int i = 0, j = 0, k = 0; i < result.length; i++){
if( j == t.length){
result[i] = u[k++];
} else if (k == u.length) {
result[i] = t[j++];
} else {
result[i] = t[j] < u [k] ? t[j++] : u[k++];
}
}
return result;
};
if(l.length <= 1){
return l;
}
return merge.apply( mergeSort.apply(Arrays.copyOfRange(l, 0, l.length / 2)),
mergeSort.apply(Arrays.copyOfRange(l, l.length / 2, l.length )));
};
System.out.println(Arrays.toString(mergeSort.apply(values)));
}
}
Некоторые моменты, касающиеся этого кода:
- Мне пришлось переименовать параметр
MergeSort
lambda отt
доl
, так какt
также используется вMerge
lambda. - Мне пришлось объявить лямбда
MergeSort
как статический член (до назначения его значения), поскольку он содержит рекурсивные вызовы к себе.