Использование потоков Java с универсальными

#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 отличное редактирование, спасибо!