Статьи

Функциональные интерфейсы Java 8 — случайные размышления, реализующие тип Scala

В одном из заданий курса « Функциональное программирование с Scala» вводится тип, называемый «Terrain» — Terrain представляет регион, части которого доступны, а части — нет. Таким образом, очень умно Terrain определяется следующим образом в задании:

1
2
3
case class Pos(x:Int, y: Int)
 
type Terrain = Pos => Boolean

По существу, Terrain — это функция, которая занимает позицию и для этой позиции возвращает логическое значение в зависимости от того, доступна эта позиция или нет!

Учитывая это определение Terrain, способ определить «бесконечный» ландшафт, где каждая позиция доступна, выполняется следующим образом:

1
val infiniteTerrain = (pos: Pos) => true

или другой ландшафт, где доступны определенные координаты, можно определить следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
def terrainFunction(vector: Vector[Vector[Char]]) : Terrain = {
 (pos: Pos) => {
  if (pos.x > vector.size - 1 || pos.y > vector(0).size - 1 || pos.x < 0 || pos.y < 0) {
   false
  } else {
   val ch = vector(pos.x)(pos.y)
   ch == 'o';
  }
 }
 
val terrain1 = terrainFunction(Vector(
     Vector('-','-','-'),
     Vector('-','o','-'),
     Vector('-','o','-'),
     Vector('-','o','-'),
     Vector('-','-','-')
     )
    )

Все очень умно.

Теперь, учитывая, что выпуск Java 8 неизбежен , можно попытаться использовать такой же (почти :-)) умный код, используя конструкции Java 8:

тогда как Terrain может быть определен как сигнатура функции в Scala, он должен быть определен как функциональный интерфейс с Java 8:

1
2
3
interface Terrain {
 public boolean isAccessible(Pos pos);
}

Учитывая этот интерфейс, бесконечный ландшафт выглядит следующим образом, используя Lambdas в Java 8:

1
Terrain infiniteTerrain = (pos) -> true;

Эквивалент terrainFunction в Java 8 может быть определен следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
public Terrain terrainFunction(char[][] arr) {
 return (pos) -> {
  if (pos.x > arr.length - 1 || pos.y > arr[0].length - 1 || pos.x < 0 || pos.y < 0) {
   return false;
  } else {
   char ch = arr[pos.x][pos.y];
   return ch == 'o';
  }
 };
}
 
char[][] arr = {
 {'-','-','-'},
 {'-','o','-'},
 {'-','o','-'},
 {'-','o','-'},
 {'-','-','-'}
};
Terrain terrain = terrainFunction(arr);
 
assertTrue(terrain.isAccessible(new Pos(1, 1)));

Достаточно близко!