Решения, упомянутые здесь, работают, но они мутируют объекты вне контекста потоков, чего следует избегать.
Таким образом, вместо использования .forEach()
, который является завершающей операцией, возвращающей void
. Правильный подход состоял бы в использовании .map()
, который, как и название, отображает одно значение в другое. В вашем случае первая операция, которую вы хотите сделать, - сопоставить Person с JSONObject. Вторая операция - это функция редуктора, в которой вы хотите уменьшить все JSONObjects до одного объекта JSONArray.
public JSONArray mapListToJsonArray(List<Person> persons) {
List<JSONObject> jsonObjects = persons
.stream()
.map(person -> {
JSONObject json = new JSONObject();
json.put("firstName", person.getFirstName());
json.put("lastName", person.getLastName());
return json;
})
.collect(Collectors.toList());
return new JSONArray(jsonObjects);
}
К сожалению, реализация json.org JSONArray не позволяет легко объединить два массива. Поэтому вместо того, чтобы сводить к JSONArray, я сначала собрал все JSONObjects в виде списка и создал из него JSONArray.
Решение выглядит еще приятнее, если вы замените выражение лямбда ссылкой на метод.
public JSONArray mapListToJsonArray(List<Person> persons) {
List<JSONObject> jsonObjects = persons
.stream()
.map(this::mapPersonToJsonObject)
.collect(Collectors.toList());
return new JSONArray(jsonObjects);
}
public JSONObject mapPersonToJsonObject(Person person) {
JSONObject json = new JSONObject();
json.put("firstName", person.getFirstName());
json.put("lastName", person.getLastName());
return json;
}
Если у вас есть больше элементов, используйте parallelStream вместо потока – user121290
http://stackoverflow.com/questions/20375176/should-i-always-use-a-parallel-stream-when-possible - не только не используйте волейбол параллельный поток! – Aerus
Я не знаю, почему я думал, что для функции forEach требуются аргументы лямбда. Благодаря! – obesechicken13