Есть ли лучший способ, чем использовать generic c WildCard в качестве параметра метода? - PullRequest
1 голос
/ 16 февраля 2020

Мне нужен метод getNextId () для трех разных карт:

private final Map<Integer, Track> tracks;
private final Map<Integer, Train> trains;

private final Map<Integer, Coach> coaches;

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

public int getNextId(Map<Integer, ?> givenMap) {
            int id = 1;
        for (int key : givenMap.keySet()) {
            if (key > id) break;
            id = key + 1;
        }
        return id;
}

Метод getNextId () в основном получает наименьший доступный идентификатор> = 1. Если существуют TrainID 1, 2, 3, 4, и пользователь удаляет поезд с идентификатором 2, следующий добавленный поезд получает идентификатор 2.

Ответы [ 2 ]

2 голосов
/ 16 февраля 2020

Напишите интерфейс или класс (назовем его MyBase), который наследуется вызовом три Track, Train и Coach.

Затем измените ваш метод:

public int getNextId(Map<Integer, ? extends MyBase> givenMap) {
    ...
}
1 голос
/ 16 февраля 2020

По сути, я бы предложил быть максимально точным. Если вы знаете, что ваша функция работает только для фиксированного набора классов, вы не должны позволять передавать любой класс - который будет применяться к ? -дорожной карте. В противном случае вы получите странные ошибки времени выполнения, потому что я могу просто предоставить HashMap<Integer, MyOwnClass> без жалоб компилятора. Кроме того, вы не можете многое сделать на ?, что оценивается в Object. Поэтому, если вам когда-нибудь понадобится изменить значения карт, у вас будет довольно большая проблема, потому что вы получите просто Object. Изменение сигнатуры методов может оказаться невозможным в настоящее время, если у вас есть существующие клиенты за пределами. Поэтому я настоятельно рекомендую не использовать ?, если вы действительно не имеете в виду «карту произвольного типа».

У вас, кажется, есть три типа, у каждого из которых есть какой-то идентификатор. Поэтому лучше всего было бы извлечь для них интерфейс и использовать его в своей реализации:

interface MyInterface { }
class Track : MyInterface { }
class Train : MyInterface { }
class Coach: MyInterface { }

Теперь легко определить ваш метод:

public int getNextId(Map<Integer, ? extends MyInterface> givenMap) { ... }

Помимо этого я могу Не понимаю, почему вы вообще используете какую-либо карту, когда вас просто интересуют клавиши . Лучше просто укажите List<Integer> или аналогичный.

...