Этот пост содержит некоторую информацию о коллекциях Scala.
Проблема?
Нам нужна функция, которая будет принимать список игроков в регби в качестве входных данных и возвращать имена тех игроков, которые играют за Лейнстера и могут пробежать 100 метров от самых быстрых до самых медленных.
Шаг 1: Представление игрока в регби.
Итак, очевидно, что мы хотим, чтобы что-то вроде POJO представляло игрока в регби. Этот
Представление должно содержать имя игрока, его команду и время, когда они могут пройти 100 метров. Давайте использовать конструкцию класса случая Scala
что устраняет необходимость в коде котельной плиты.
|
1
|
case class RugbyPlayerCaseClass(team: String, sprintTime100M: BigDecimal, name: String) |
Шаг 2: Создайте игроков в регби
|
1
2
3
4
5
|
val lukeFitzGerald = RugbyPlayerCaseClass('Leinster', 10.2, 'Luke Fitzgerald');val fergusMcFadden = RugbyPlayerCaseClass('Leinster', 10.1, 'Fergus McFadden');val rog = RugbyPlayerCaseClass('Leinster', 12, 'Ronan O'Gara');val tommyBowe = RugbyPlayerCaseClass('Ulster', 10.3, 'Tommy Bowe');val leoCullen = RugbyPlayerCaseClass('Leinster', 15, 'Leo Cullen'); |
Код выше должен быть понятен. Различные игроки в регби создаются. Обратите внимание на вывод текста. Нет необходимости объявлять игроков в регби типами RugbyPlayers. Вместо этого это выводится. Еще одна интересная вещь — это ключевое слово val . Это означает, что ссылка неизменна. Это эквивалент final в Java.
Шаг 3: Напишите функцию
|
1
2
|
def validByAge(in: List[RugbyPlayerCaseClass]) = in.filter(_.team == 'Leinster').sortWith(_.sprintTime100M < _.sprintTime100M).map(_.name); |
Ключевые моменты относительно этой функции:
- Функция начинается с ключевого слова
defобозначающего объявление функции. - Список экземпляров RugbyPlayerCaseClass принимается в качестве входных данных. Тип List является типом Scala.
- Тип возврата не является обязательным. В этом случае он не указан явно, так как выводится.
- Часть слева от = — это то, что делает функция. В этом случае функция вызывает три оператора сбора разностей.
-
.filter(_.team =='Leinster)— выполняет итерацию по каждому элементу в списке. На каждой итерации _ заполняется текущим значением в списке. Если свойство команды текущего игрока в регби — Leinster, элемент включается в результирующую коллекцию. -
.sortWith(_.sprintTime100M < _.sprintTime100M)— sortWith — это специальный метод, который мы можем использовать для сортировки коллекций. В этом случае мы сортируем выходные данные из предыдущего оператора коллекции и сортируем на основе sprintTime для 100M. -
.map(_.name)— это сопоставляет каждый элемент из вывода оператора сортировки только с именем свойства.
-
- Тело функции не обязательно должно быть заключено в {}, потому что это только один строчный код.
- Нет необходимости в возврате. В Scala все, что оценивает последняя строка, будет возвращено. В этом примере, поскольку есть только одна строка, последняя строка является первой строкой.
Напоследок — собери все вместе.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
object RugbyPlayerCollectionDemos { def main(args: Array[String]){ println('Scala collections stuff!'); showSomeFilterTricks(); } // Case class remove need for boiler plater code. case class RugbyPlayerCaseClass(team: String, sprintTime100M: BigDecimal, name: String) def showSomeFilterTricks() { // team: String, sprintTime100M: Int, name: String val lukeFitzGerald = RugbyPlayerCaseClass('Leinster', 10.2, 'Luke Fitzgerald'); val fergusMcFadden = RugbyPlayerCaseClass('Leinster', 10.1, 'Fergus McFadden'); val rog = RugbyPlayerCaseClass('Munster', 12, 'Ronan O'Gara'); val tommyBowe = RugbyPlayerCaseClass('Ulster', 10.3, 'Tommy Bowe'); val leoCullen = RugbyPlayerCaseClass('Leinster', 15, 'Leo Cullen'); println(validByAge(List(lukeFitzGerald, fergusMcFadden, rog, tommyBowe, leoCullen))); } def validByAge(in: List[RugbyPlayerCaseClass]) = in.filter(_.team == 'Leinster').sortWith(_.sprintTime100M < _.sprintTime100M).map(_.name);} |
Вышеприведенная программа выведет:
|
1
2
|
Scala collections stuff!List(Luke Fitzgerald, Fergus McFadden, Leo Cullen) |
Нечто подобное в Java Pre Java 8, для реализации той же функциональности в Java было бы гораздо больше кода.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
public class RugbyPLayerCollectionDemos { public static void main(String args[]) { RugbyPLayerCollectionDemos collectionDemos = new RugbyPLayerCollectionDemos(); collectionDemos.showSomeFilterTricks(); } public void showSomeFilterTricks() { // team: String, sprintTime100M: Int, name: String final RugbyPlayerPOJO lukeFitzGerald = new RugbyPlayerPOJO('Leinster', new BigDecimal(10.2), 'Luke Fitzgerald'); final RugbyPlayerPOJO fergusMcFadden = new RugbyPlayerPOJO('Leinster', new BigDecimal(10.1), 'Fergus McFadden'); final RugbyPlayerPOJO rog = new RugbyPlayerPOJO('Munster', new BigDecimal(12), 'Ronan O'Gara'); final RugbyPlayerPOJO tommyBowe = new RugbyPlayerPOJO('Ulster', new BigDecimal(10.3), 'Tommy Bowe'); final RugbyPlayerPOJO leoCullen = new RugbyPlayerPOJO('Leinster', new BigDecimal(15), 'Leo Cullen'); List rugbyPlayers = Arrays.asList(lukeFitzGerald, fergusMcFadden, rog, tommyBowe, leoCullen); System.out.println(filterRugbyPlayers(rugbyPlayers)); } /** * Return the names of Leinster Rugby players in the order of their sprint times. */ public List filterRugbyPlayers(List pojos) { ArrayList leinsterRugbyPlayers = new ArrayList (); for (RugbyPlayerPOJO pojo: pojos) { if (pojo.getTeam().equals('Leinster')) { leinsterRugbyPlayers.add(pojo); } } RugbyPlayerPOJO [] rugbyPlayersAsArray = leinsterRugbyPlayers.toArray(new RugbyPlayerPOJO[0]); Arrays.sort(rugbyPlayersAsArray, new Comparator () { public int compare(RugbyPlayerPOJO rugbyPlayer1, RugbyPlayerPOJO rugbyPlayer2) { return rugbyPlayer1.getSprintTime100M().compareTo(rugbyPlayer2.getSprintTime100M()); } }); List rugbyPlayersNamesToReturn = new ArrayList (); for (RugbyPlayerPOJO rugbyPlayerPOJO: rugbyPlayersAsArray) { rugbyPlayersNamesToReturn.add(rugbyPlayerPOJO.getName()); } return rugbyPlayersNamesToReturn; } class RugbyPlayerPOJO { private BigDecimal sprintTime100M; private String team; private String name; public RugbyPlayerPOJO(String team, java.math.BigDecimal sprintTime100M, String name) { this.name = name; this.sprintTime100M = sprintTime100M; this.team = team; } public BigDecimal getSprintTime100M() { return sprintTime100M; } public String getTeam() { return team; } public String getName() { return name; } }} |
Выручает ли Java 8?
Да. Согласно спецификациям проекта Lambda, Java 8 будет иметь похожие функции фильтра, отображения и сортировки . Функциональность этого поста в Java 8 будет выглядеть примерно так:
|
01
02
03
04
05
06
07
08
09
10
|
List rugbyPlayers = Arrays.asList(lukeFitzGerald, fergusMcFadden, rog, tommyBowe, leoCullen);//...//...List filteredPLayersNames = rugbyPlayers.filter(e -> e.getTeam.equals('Leinster')). sorted((a, b) -> a.getSprintTime100M() - b.getSprintTime100M()).mapped(e -> {return e.getName();}).into(new List<>()); |
Так что Java 8 определенно догоняет многое в этом отношении. Но будет ли этого достаточно?
Ссылка: Scala: Коллекции 1 от нашего партнера JCG Алекса Стейвли в блоге Techlin в Дублине .