83 подписчика
🖥 Как с помощью лямбда выражения обработать определенную часть строки в коллекции?
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,
"Joseph Smith", "Thomas Doyle", "Ronald Pratt", "Thomas Spencer", "King Lee",
"Gregory Smith", "Leroy Zimmerman", "Lee Smith", "Michael Harrington",
"Lee Daniels","Eugene Williams", "Lee Terry", "Arnold Fowler", "Billy Harrison",
"Lee Bennett", "Lee Evans", "Ronald Diaz", "Leonard King", "Timothy Smith",
"George Lee", "King Mann", "Dean Wright"
);
list.stream()
.filter(s -> s.contains("K") || s.contains("S"))
.filter(s -> !s.startsWith("K")&&!s.startsWith("S"))
.sorted().distinct()
.collect(Collectors.toList());
Метод должен вернуть имена людей, чья фамилия начинается с K или S, в формате имя + первая буква фамилии, например "David Z.". Список должен быть отсортирован по алфавиту и состоять только из уникальных значений
Ответ
Для данных, представленных в формате "{firstName} {lastName}" можно отфильтровать слова при помощи String::matches и регулярного выражения типа "\\w+ [KS]\\w+". Соответственно, к отфильтрованным слов достаточно будет применить String::substring:
List<String> list = Arrays.asList(
"Joseph Smith", "Thomas Doyle", "Ronald Pratt", "Thomas Spencer", "King Lee",
"Gregory Smith", "Leroy Zimmerman", "Lee Smith", "Michael Harrington", "Lee Daniels","Eugene Williams",
"Lee Terry", "Arnold Fowler", "Billy Harrison", "Lee Bennett", "Lee Evans", "Ronald Diaz",
"Leonard King", "Timothy Smith", "George Lee", "King Mann", "Dean Wright"
);
List<String> fixed = list.stream()
.filter(s -> s.matches("\\w+ [KS]\\w+"))
.map(s -> s.substring(0, s.indexOf(" ") + 2) + ".")
.sorted()
.distinct()
.collect(Collectors.toList());
System.out.println(fixed);
// -> [Gregory S., Joseph S., Lee S., Leonard K., Thomas S., Timothy S.]
Если имена состоят из трех и больше частей, но фамилией является последняя часть, регулярное выражение ".+ [KS]\\w+" и поиск фамилии следует исправить (искать последний пробел при помощи String::lastIndexOf):
List<String> list = Arrays.asList(
"Joseph Smith", "Thomas Doyle", "Ronald Pratt Kimberly", "Thomas Spencer", "King Lee Roy Stapleton",
"Gregory Smith", "Leroy Zimmerman", "Lee Smith Jacob", "Michael Harrington", "Lee Daniels","Eugene Williams",
"Lee Terry", "Arnold Fowler", "Billy Harrison", "Lee Bennett", "Lee Evans", "Ronald Diaz",
"Leonard King", "Timothy Smith", "George Lee", "King Mann", "Dean Wright"
);
List<String> fixed = list.stream()
.filter(s -> s.matches(".+ [KS]\\w+"))
.map(s -> s.substring(0, s.lastIndexOf(" ") + 2) + ".")
.sorted()
.distinct()
.collect(Collectors.toList());
System.out.println(fixed);
// -> [Gregory S., Joseph S., King Lee Roy S., Leonard K., Ronald Pratt K., Thomas S., Timothy S.]
Ещё один вариант: вместо String.substring применить String::replaceAll для замены части фамилии на точку -- выглядит более "красиво":
List<String> fixed = list.stream()
.filter(s -> s.matches("(.+ [KS])(.*$)"))
.map(s -> s.replaceAll("(.+ [KS])(.*$)", "$1."))
.sorted()
.distinct()
.collect(Collectors.toList());
👉 Пишите ваше решение в комментариях👇
2 минуты
10 марта 2023