Не спрашивайте «лямбды / потоки», но фактическое улучшение.
Когда вы используете
private static void test(List<Foo> a) throws Exception {
Map<TypeOfFooA, TypeOfFooB> seen = new HashMap<>();
for(Foo f: a) {
TypeOfFooB fooB = f.getFooB(), previous = seen.putIfAbsent(f.getFooA(), fooB);
if(previous != null && !fooB.equals(previous))
throw new Exception("some message goes here...");
}
}
, вы выполняете операцию за один проход вместо вложенных циклов. Это делает разницу между линейной и квадратичной c сложностью времени. Который имеет большее влияние, чем «выглядеть круто».
Вы можете переписать это для использования Stream API, например
private static void test(List<Foo> a) throws Exception {
Map<TypeOfFooA, TypeOfFooB> seen = a.stream()
.collect(Collectors.toMap(Foo::getFooA, Foo::getFooB,
(previous, fooB) -> {
if(!fooB.equals(previous))
throw new RuntimeException("some message goes here...");
return previous;
}));
}
Но это не рекомендуется. Сбор на карту, которая впоследствии не нужна, в сочетании с использованием функции слияния / сокращения для проверки и создания исключения, может удивить читателей, и он работает только для непроверенных исключений. Кроме того, функция выброса не может получить доступ ни к экземпляру Foo
, ни к клавише FooA
для создания сообщения об исключении.
Я рекомендую остаться с l oop.