Объединение элементов List
На вход получаю некий List
@Override
public List transformList(List list) {
return list;
}
если что это переопределенный метод ResultTransformer() структура получаемого List следующая:
List {{1, 2, 3, List {a, b, c}, 5, 6, 7}, {1, 2, 3, List {d, e, f}, 5, 6, 7}}
Состоит из двух элементов, данные повторяются, внутри каждого элемента еще один List где данные уже пересекаться не будут
Есть-ли какое-то решение чтобы привести этот List к виду:
List {1, 2, 3, List {{a, b, c}, {d, e, f}}, 5, 6, 7}
Ответы (2 шт):
У вас в вопросе метод, принимающий и возвращающий лист, а в комментариях 2 джейсона.не знаю, как это связано, но, поскольку я вижу конкретные примеры джейсонов в комментариях, а в вопросе некое схематическое отображение листов, то предполагаю, что все таки у вас на входе джейсон. раз это джейсон, а мы хотим каким-то образом работать с данными с помощью java, то мы бы хотели его распарсить и превратить в объекты. когда мы получим объекты, то с ними выполним любые преобразования. я пользуюсь lombok, чтобы не писать гетерры, сеттеры и т.д., а также гугловым Gson, чтобы парсить джейсон(вы можете сгенерировать геттеры, сеттеры и т.д. и использовать любой другой сериализатор). итак создадим 2 класса, в которые и будем парсить наш джейсон:
import java.util.ArrayList;
import java.util.List;
@lombok.Data
public class Response {
private String id;
private String title;
private String persistDateTime;
private String countValuable;
private String viewCount;
private String countAnswer;
private String username;
private String reputationCount;
private List<Tags> tags;
public List<Tags> getTags() {
if (tags==null) tags = new ArrayList<>();
return tags;
}
}
@lombok.Data
class Tags {
private String id;
private String name;
private String description;
}
это просто модели. коллекцию объектов Response мы и получим в результате десериализации нашего джейсона. тогда для того, чтобы распарсить наш джейсон и привести его к указанному вами виду напишем специальный метод, принимающий стринг с джейсоном и возвращающий коллекцию в нужном нам виде:
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class Main {
private final static Type TYPE = new TypeToken<List<Response>>(){}.getType();
private final static Gson GSON = new Gson();
public Collection transform(String json) {
Collection<Response> responseList = GSON.fromJson(json, TYPE);
Map<String, Response> result = new LinkedHashMap<>();
for (Response response : responseList) {
if (result.containsKey(response.getId())) {
result.get(response.getId()).getTags().addAll(response.getTags());
}
else result.put(response.getId(), response);
}
return result.values();
}
}
Дмитрий спасибо за предоставленное решение - оно также имеет место быть, но я решил вопрос немного иначе:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@Repository
public class QuestionDtoDaoImpl extends ReadWriteDaoImpl<QuestionDto, Long> implements QuestionDtoDao {
@SuppressWarnings("unchecked")
@Override
public List<QuestionDto> getQuestionDtoList() {
List<QuestionDto> questionDto = new ArrayList<>();
try {
questionDto = entityManager.createQuery("SELECT "
+ "q.id, "
+ "q.title, "
+ "q.user.fullName, "
+ "q.user.reputationCount, "
+ "q.viewCount, "
+ "q.countValuable, "
+ "q.persistDateTime, "
+ "t.id, "
+ "t.name, "
+ "t.description, "
+ "(SELECT COUNT (a) FROM Answer a WHERE a.question.id = q.id), "
+ "(SELECT a.isHelpful FROM Answer a WHERE a.question.id = q.id) "
+ "FROM Question q JOIN q.tags t")
.unwrap(Query.class)
.setResultTransformer(new ResultTransformer() {
@Override
public Object transformTuple(Object[] objects, String[] strings) {
TagDto tagDto = TagDto.builder()
.id((Long) objects[7])
.name((String) objects[8])
.description((String) objects[9])
.build();
List<TagDto> tagDtoList = new ArrayList<>();
tagDtoList.add(tagDto);
return QuestionDto.builder()
.id((Long) objects[0])
.title((String) objects[1])
.username((String) objects[2])
.reputationCount((Integer) objects[3])
.viewCount((Integer) objects[4])
.countValuable((Integer) objects[5])
.persistDateTime((LocalDateTime) objects[6])
.tags(tagDtoList)
.countAnswer(((Number) objects[10]).intValue())
.isHelpful((Boolean) objects[11])
.build();
}
@Override
public List transformList(List list) {
Map<Long, QuestionDto> result = new TreeMap<>(Comparator.reverseOrder());//Comparator.naturalOrder()
for (Object obj : list) {
QuestionDto questionDto = (QuestionDto) obj;
if (result.containsKey(questionDto.getId()))
result.get(questionDto.getId()).getTags().addAll(questionDto.getTags());
else result.put(questionDto.getId(), questionDto);
}
return new ArrayList<>(result.values());
}
})
.getResultList();
} catch (Exception e) {
e.printStackTrace();
}
return questionDto;
}
PS. Есть-ли возможность переписать этот код с помощью стрим?