#java #generics #lambda #stream
Вопрос:
У меня есть класс ниже:
@Data
public class PagedSchoolDto {
private final Integer count;
private final Map<String, List<School>> content;
private final String pagingState;
private final Boolean hasNext;
public PagedSchoolDto(final Slice<School> slice) {
this.content = slice.getContent().stream().collect(
Collectors.groupingBy(School::getId, () -> new TreeMap<>(new UUIDComparator()), Collectors.toList()));
this.count = slice.getContent().size();
this.hasNext = slice.hasNext();
this.pagingState = getPagingState(slice);
}
@Nullable
private static String getPagingState(final Slice<School> slice) {
if (slice.hasNext()) {
CassandraPageRequest pageRequest = (CassandraPageRequest) slice.nextPageable();
return pageRequest.getPagingState().toString();
} else {
return null;
}
}
}
Теперь я хочу сделать свой код универсальным, чтобы я мог использовать этот класс и для других типов объектов, как показано ниже:
@Data
public class PagedDto<T> {
private final Integer count;
private final Map<String, List<T>> content;
private final String pagingState;
private final Boolean hasNext;
public PagedDto(final Slice<T> slice) {
this.content = slice.getContent().stream().collect(
Collectors.groupingBy(<T>::getId, () -> new TreeMap<>(new UUIDComparator()), Collectors.toList()));
this.count = slice.getContent().size();
this.hasNext = slice.hasNext();
this.pagingState = getPagingState(slice);
}
@Nullable
private static <T> String getPagingState(final Slice<T> slice) {
if (slice.hasNext()) {
CassandraPageRequest pageRequest = (CassandraPageRequest) slice.nextPageable();
return pageRequest.getPagingState().toString();
} else {
return null;
}
}
}
Все мои классы имеют свойство под названием ID, которое является типом UUID, поэтому компаратор должен нормально работать со всеми универсальными типами. Проблема в том, что я не уверен, как написать функцию Collectors.groupingBy и код поставщика, так как второй фрагмент кода выдает ошибку компиляции.
Ответ №1:
Ваш универсальный тип T не указан, например, «Объект», который не предоставляет метод getId. Чтобы получить доступ к getId в общем коде, T должен расширить интерфейс с помощью метода getId, который реализуется любым классом, используемым с PagedDto:
public interface WithId {
UUID getId();
}
public class School implements WithId {
private UUID id;
@Override
public UUID getId() {
return id;
}
public class PagedDto<T extends WithId> {
...
Комментарии:
1. @matteo-nnz отличное редактирование, спасибо!