Есть ли лучший способ, которым я могу обрабатывать мой базовый базовый класс в наследовании классов?

У меня проблемы с использованием и пониманием дженериков. Я работал с дженериками раньше, но теперь я дошел до того, что не могу дальше

Вот мой основной класс, который должен быть расширен другими классами:

public class BaseFiller<T> {

private WorkBook workBook;
private List<T> act_Bwa;
private List<T> act_Balance;
private List<T> p_l_v_e_L;


public BaseFiller(WorkBook workBook,
                  List<T> act_Bwa,
                  List<T> act_Balance,
                  List<T> p_l_v_e_L) {
    this.workBook = workBook;
    this.act_Bwa = act_Bwa;
    this.act_Balance = act_Balance;
    this.p_l_v_e_L = p_l_v_e_L;
}


protected static <T> Predicate<T> distinctByProperty(Function<? super T, ?> keyExtractor) {
    Map<Object, Boolean> seen = new ConcurrentHashMap<>();
    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}



protected static <T> Map<Integer, String> mapListToMap(Collection<? extends T> entityList, Function<? super T, Integer> intProperty,
                                                           Function<? super T, String> stringProperty) {
    return entityList.stream()
            .collect(Collectors.toMap(intProperty, stringProperty));
}


 //Getter & Setter

 }

Следующий класс расширяет базовый класс:

public class FinanceBalanceFiller<T> extends BaseFiller<T> {

.
.
.


public FinanceBalanceFiller(WorkBook workBook, List<T> act_Bwa,
                            List<T> act_Balance,
                            List<T> p_l_v_e_L) {
    super(workBook, act_Bwa, act_Balance, p_l_v_e_L);
}



public Map<Integer, String> makeMapFromAllLists() {
    List<ResultlinevaluesEntity> res = new ArrayList<>();
    for (List<ResultlinevaluesEntity> list : getAct_Bwa()) {
        res.addAll(list);
    }

    //removes all duplicates from List by DbNr
    List<ResultlinevaluesEntity> resWithoutDuplicates = res.stream()
            .filter(distinctByProperty(ResultlinevaluesEntity::getDb_nr))
            .collect(Collectors.toList());

    //creates HashMap (Key = DbNr, Value = name)
    return mapListToHashMap(resWithoutDuplicates, ResultlinevaluesEntity::getDb_nr,
            ResultlinevaluesEntity::getName);
}

В методе makeMapFromAllLists () у меня проблемы в цикле For. Это выдает ошибку, что типы не совместимы друг с другом.

Ошибка: (116, 68) Java: несовместимые типы: T не может быть преобразован в java.util.List

Я понимаю это, и я изменил это так:

    List<T> res = new ArrayList<>();
    for (List<T> list : getAct_Bwa()) {
        res.addAll(list);
    }

Но это тоже не работает, потому что типы здесь тоже не подходят. Кроме того, у меня возникают проблемы с Methdode differentByProperty из базового класса. Здесь компилятор говорит:

На нестатический метод нельзя ссылаться из статического контекста

В то же время я совершенно сбит с толку и не могу идти дальше.

Итак, моя цель состоит в том, чтобы все методы в методе makeMapFromAllLists () обслуживали не только ListType «ResultLineValuesEntity», но и другие типы.

Может ли кто-нибудь помочь мне и показать мне, как бороться с дженериками на этом этапе?

Всего 1 ответ


Это использование addAll вместо add , но существуют упрощения:

List<ResultlinevaluesEntity> res = new ArrayList<>();
for (List<ResultlinevaluesEntity> actBwa : getAct_Bwa()) {
    res.add(actBwa);
}

List<ResultlinevaluesEntity> res = new ArrayList<>();
res.addAll(getAct_Bwa());

List<ResultlinevaluesEntity> res = new ArrayList<>(getAct_Bwa());

После отредактированного вопроса: (не желая параметр типа T)

Существует (иногда неизбежный) (анти) шаблон параллельных иерархий классов

Если у вас есть базовый класс Item / Entity ItemBase.

class ItemBase
class ItemA extends ItemBase
class ItemB extends ItemBase

И контейнер базового класса ContainerBase

class ContainerBase<T extends ItemBase>
    List<T> items
    List<T> getItems();

class ContainerA extends ContainerBase<ItemA>
class ContainerB extends ContainerBase<ItemB>

Это хороший способ иметь безопасные с точки List<ItemA> типов классы с различием между List<ItemA> и List<ItemB> . В противном случае вы могли бы просто List<ItemBase> .

Лучше всего было бы не нуждаться в ContainerA и ContainerB .

Вы также можете сделать (если вы не хотите параметр):

class ContainerBase
    List<ItemBase> items;
    public List<ItemBase> getItems();

class ContainerA extends ContainerBase
    @Override
    public List<ItemA> getItems() {
        return items.stream().map(ItemA.class::cast).collect(Collectors.toList());
    }

class ContainerB extends ContainerBase
    @Override
    public List<ItemB> getItems() {
        return items.stream().map(ItemB.class::cast).collect(Collectors.toList());
    }

Есть идеи?

10000