JAVA. Параметризация класса, появилась ошибка ClassCastException

Всем привет! Прошу помощи.

Абстрактный класс AbstractStorage переделываю в параметризованный абстрактный класс AbstractStorage<SK>. Соотвественно также методы делаю параметризованными. Тесты по дочернему классу ListStorage или любому другому ломаются с ошибкой

ClassCastException java.lang.String cannot be cast to java.lang.Integer

Понимаю, что где-то передаю неправильный тип, но как исправить пока не понимаю. Прошу помочь и объяснить где ошибка.

ошибка

Родительский класс:

public abstract class AbstractStorage<SK> implements Storage {

    private static final Logger LOG = Logger.getLogger(AbstractStorage.class.getName());

    protected abstract Integer findIndex(String uuid);

    protected abstract void doUpdate(Resume resume, SK index);

    protected abstract void doSave(Resume resume, SK index);

    protected abstract Resume doGet(SK searchKey);

    protected abstract void doDelete(SK searchKey);

    protected abstract List<Resume> doGetList();

    private SK doExistException(String uuid) {
        Integer index = findIndex(uuid);
        if (index < 0) {
            LOG.warning("Резюме " + uuid + " не существует");
            throw new NotExistStorageException(uuid);
        }
        return (SK) index;
    }

    private SK doNotExistException(String uuid) {
        Integer index = findIndex(uuid);
        if (index >= 0) {
            LOG.warning("Резюме " + uuid + " уже существует");
            throw new ExistStorageException(uuid);
        }
        return (SK) index;
    }

    public final void update(Resume resume) {
        LOG.info("Update " + resume);
        String uuid = resume.getUuid();
        doUpdate(resume, doExistException(uuid));
        System.out.println("Резюме " + resume.getUuid() + " успешно обновлено");
    }

    public final void save(Resume resume) {
        LOG.info("Save " + resume);
        String uuid = resume.getUuid();
        doSave(resume, doNotExistException(uuid));
        System.out.println("Резюме " + resume.getUuid() + " успешно добавлено.");
    }

    public final Resume get(String uuid) {
        LOG.info("Get " + uuid);
        doExistException(uuid);
        System.out.println("Резюме " + uuid + " найдено");

        return doGet((SK) uuid);
    }

    public final void delete(String uuid) {
        LOG.info("Delete " + uuid);
        doExistException(uuid);
        doDelete((SK) uuid);
        System.out.println("Резюме " + uuid + " удалено.");
    }

    public final List<Resume> getAllSorted() {
        List<Resume> list = doGetList();
        list.sort(Resume::compareTo);
        return list;
    }
}

Наследник:

public class ListStorage extends AbstractStorage<Integer> {

    private List<Resume> listStorage = new ArrayList<>();

    @Override
    public void clear() {
        listStorage.clear();
    }

    @Override
    public List<Resume> doGetList() {
        return listStorage;
    }

    @Override
    public void doUpdate(Resume resume, Integer index) {
        listStorage.set(index, resume);
    }

    @Override
    public void doSave(Resume resume, Integer index) {
        listStorage.add(resume);
    }

    @Override
    public Resume doGet(Integer searchKey) {
        //int index = findIndex(searchKey);
        //return listStorage.get(index);
        return listStorage.get(searchKey);
    }

    @Override
    public void doDelete(Integer searchKey) {
        //int index = findIndex(searchKey);
        //listStorage.remove(index);
        listStorage.remove(searchKey);
    }

    @Override
    public int size() {
        return listStorage.size();
    }

    @Override
    protected Integer findIndex(String uuid) {
        for (int i = 0; i < listStorage.size(); i++) {
            if (listStorage.get(i).getUuid().equals(uuid)) {
                return i;
            }
        }
        return -1;
    }
}

Ответы (1 шт):

Автор решения: Alexandr

Если честно не до конца понимаю зачем Вам вообще параметризация. uuid - строка, по которой мы каждый раз находим индекс, который всегда имеет тип Integer и проверяем либо он есть, либо его нет. При необходимости кидаем исключение.

На мой взгляд параметризация не нужна:

public abstract class AbstractStorage implements Storage {

    private static final Logger LOG = Logger.getLogger(AbstractStorage.class.getName());

    protected abstract Integer findIndex(String uuid);

    protected abstract void doUpdate(Resume resume, Integer index);

    protected abstract void doSave(Resume resume, Integer index);

    protected abstract Resume doGet(Integer searchKey);

    protected abstract void doDelete(Integer searchKey);

    protected abstract List<Resume> doGetList();

    private Integer doExistException(String uuid) {
        Integer index = findIndex(uuid);
        if (index < 0) {
            LOG.warning("Резюме " + uuid + " не существует");
            throw new NotExistStorageException(uuid);
        }
        return index;
    }

    private Integer doNotExistException(String uuid) {
        Integer index = findIndex(uuid);
        if (index >= 0) {
            LOG.warning("Резюме " + uuid + " уже существует");
            throw new ExistStorageException(uuid);
        }
        return index;
    }

    public final void update(Resume resume) {
        LOG.info("Update " + resume);
        String uuid = resume.getUuid();
        doUpdate(resume, doExistException(uuid));
        System.out.println("Резюме " + resume.getUuid() + " успешно обновлено");
    }

    public final void save(Resume resume) {
        LOG.info("Save " + resume);
        String uuid = resume.getUuid();
        doSave(resume, doNotExistException(uuid));
        System.out.println("Резюме " + resume.getUuid() + " успешно добавлено.");
    }

    public final Resume get(String uuid) {
        LOG.info("Get " + uuid);
        System.out.println("Резюме " + uuid + " найдено");
        return doGet(doExistException(uuid));
    }

    public final void delete(String uuid) {
        LOG.info("Delete " + uuid);
        doDelete(doExistException(uuid));
        System.out.println("Резюме " + uuid + " удалено.");
    }

    public final List<Resume> getAllSorted() {
        List<Resume> list = doGetList();
        list.sort(Resume::compareTo);
        return list;
    }
}

Думаю, что можно изменить родительский класс так:

public abstract class AbstractStorage<R, U> implements Storage<R, U> {

    private static final Logger LOG = Logger.getLogger(AbstractStorage.class.getName());

    protected abstract Integer findIndex(U uuid);

    protected abstract void doUpdate(R resume, Integer index);

    protected abstract void doSave(R resume, Integer index);

    protected abstract R doGet(Integer searchKey);

    protected abstract void doDelete(Integer searchKey);

    protected abstract List<R> doGetList();

    private Integer doExistException(U uuid) {
        Integer index = findIndex(uuid);
        if (index < 0) {
            LOG.warning("Резюме " + uuid + " не существует");
            throw new NotExistStorageException(uuid);
        }
        return index;
    }

    private Integer doNotExistException(U uuid) {
        Integer index = findIndex(uuid);
        if (index >= 0) {
            LOG.warning("Резюме " + uuid + " уже существует");
            throw new ExistStorageException(uuid);
        }
        return index;
    }

    public final void update(R resume) {
        LOG.info("Update " + resume);
        U uuid = resume.getUuid();
        doUpdate(resume, doExistException(uuid));
        System.out.println("Резюме " + resume.getUuid() + " успешно обновлено");
    }

    public final void save(R resume) {
        LOG.info("Save " + resume);
        U uuid = resume.getUuid();
        doSave(resume, doNotExistException(uuid));
        System.out.println("Резюме " + resume.getUuid() + " успешно добавлено.");
    }

    public final R get(U uuid) {
        LOG.info("Get " + uuid);
        System.out.println("Резюме " + uuid + " найдено");
        return doGet(doExistException(uuid));
    }

    public final void delete(U uuid) {
        LOG.info("Delete " + uuid);
        doDelete(doExistException(uuid));
        System.out.println("Резюме " + uuid + " удалено.");
    }

    public final List<R> getAllSorted() {
        List<R> list = doGetList();
        list.sort(R::compareTo);
        return list;
    }
}

И соответственно дочерний класс:

public class ListStorage extends AbstractStorage<Resume, String> {

    private final List<Resume> listStorage = new ArrayList<>();

    ...
}
→ Ссылка