Ярлык для списка-> поток-> карта () -> список - PullRequest
3 голосов
/ 29 сентября 2019

Я часто конвертирую списки, подобные этому

myList.stream().map(el -> el.name).collect(Collectors.toList())

Есть ли более короткая версия для этого?

Ответы [ 4 ]

4 голосов
/ 29 сентября 2019

Я думаю, что вы должны придерживаться того, что у вас уже есть.Почему?

  1. Это уже одна строка.Нет смысла пытаться сжать его дальше.
  2. Это идиоматично.Java-разработчики привыкли читать такие преобразования, как ваши, и если они повсеместно встречаются в вашем коде, программисты, которые читают ваш код, будут еще более привыкли к нему.Даже оборачивая его в метод, как предложил @QBrute, хотя и хорошая идея, это может повредить читабельности, потому что читатели не привыкли к этому методу.

Помните: краткость - не цель.Ясность есть.Эти два часто идут рука об руку, но не всегда, и я чувствую, что они могут не в вашем случае.

Резервирование: Мой стиль и вкус в пользу ссылки на метод, который использует @Aomine, но этодело вкуса.Используйте его, если считаете его более понятным, не только потому, что он на несколько символов короче.

3 голосов
/ 29 сентября 2019

Вы можете статически импортировать Collectors.*, а затем использовать метод mapping(Function, Collector), например:

myList.stream().collect(mapping(T::getName, toList()));

Где T::getName - ссылка на метод, а T -Тип элементов в Списке.Использование этого более читабельно и практически идентично письму: el -> el.name

3 голосов
/ 29 сентября 2019

Вы можете создать статический вспомогательный метод, который выполняет всю работу:

public static <FROM, TO> List<TO> convert(List<FROM> from, Function<FROM, TO> function) {
    return from.stream().map(function).collect(Collectors.toList());
}

Все, что вам нужно сделать, это предоставить свой список и любую функцию отображения:

List<YourClass> yourList = ...;
Function<YourClass, String> func = YourClass::getName;
List<String> converted = convert(yourList, func);

Или дажеболее кратко:

List<String> converted = convert(yourList, YourClass::getName);
3 голосов
/ 29 сентября 2019

Нет более короткого способа сделать это с помощью потоков.

Вы можете импортировать import static java.util.stream.Collectors.*; и затем использовать toList следующим образом, чтобы немного сократить код, но не считая этого.Ниже приведено такое же компактное использование потоков:

myList.stream().map(el -> el.name).collect(toList());

Вы также можете использовать ссылку на метод

myList.stream().map(T::getName).collect(toList()); 

, где T - это имя типа, содержащее nameхотя это не гарантируется, что оно будет короче в зависимости от длины имени типа, но обеспечивает лучшую читаемость , что очень важно.

В конечном итоге, как и сказано, оно столь же компактноэто получает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...