Почему мой список содержит целые числа?
Итак, у меня есть следующий метод, который подделывает базу данных локально:
public class TestClassDao implements ClassDao {
// ...
private static List<ClassDto> classes = new ArrayList<>();
@Override
public List<ClassDto> getClassesByIds(List<Long> classIds) {
List<ClassDto> results = new ArrayList<>();
for (ClassDto classInstance : classes) {
if (classIds.contains(classInstance.getId())) {
results.add(classInstance);
}
}
return cloner.deepClone(results);
}
//...
}
Я был озадачен, потому что результаты всегда возвращались пустыми. Я прошел через отладчик в Android Studio и обнаружил, что проверка contains всегда возвращает false
, даже если известно, что правильный идентификатор присутствует.
Прослеживая, что назад с отладчиком, я нашел то, что я подозреваю, чтобы быть виновником: согласно отладчику, List<Long> classIds
содержит*Integer* объекты. Что дает? Я не знаю, как отладить это дальше.
Правка:
Вот вывод отладчика, на котором основан вопрос:
Правка 2:
Вот как тестовые данные загружаются в хранилище данных, вы можете видеть, что я правильно передаю значения Long
:
public static ClassDto getClassTestData(int classId) {
ClassDto classDto = new ClassDto();
switch (classId) {
case 1:
classDto.setId(1L);
classDto.setName("207E - Mrs. Randolph");
classDto.setTeacher(getTeacherTestData());
classDto.setStudents(getStudentsTestData());
return classDto;
case 2:
classDto.setId(2L);
classDto.setName("209W - Mr. Burns");
classDto.setTeacher(getTeacherTestData());
return classDto;
case 3:
classDto.setId(3L);
classDto.setName("249E - Mr. Sorola");
classDto.setTeacher(getTeacherTestData());
return classDto;
default:
return null;
}
}
Правка 3:
Вот Дао, где школьная информация сохраняется/извлекается из нее. Проблема возникает где-то между временем вставки данных и временем их удаления. Он входит с типом Long
и выходит с типом Int
@Dao
public interface SchoolDao {
@Query("SELECT * FROM schools")
List<SchoolDto> getAllSchools();
@Insert
void insertSchool(SchoolDto schoolDto);
}
4 ответа:
Вау, какой кошмар. Я нашел преступника.
Я создал
TypeConverter
, чтобы превратитьList<Integer>
to в строку (и обратно), чтобы она могла храниться в одном столбце в БД в комнате без необходимости изменять существующие DTOs. Однако, когда я переключился на использование типовLong
в качестве идентификаторов, мне не удалось преобразовать один общий аргумент ниже в преобразователе; внимательно посмотрите на следующий код:public class IdsListConverter { @TypeConverter public List<Long> idsFromString(String value) { Gson gson = new Gson(); if (value == null || value.isEmpty()) { return null; } else { Type resultType = new TypeToken<List<Integer>>(){}.getType(); return gson.fromJson(value, resultType); } } @TypeConverter public String idsToString(List<Long> ids) { if (ids == null) { return null; } else { Gson gson = new Gson(); return gson.toJson(ids); } } }
Похоже, что вы нашли свою проблему:
Type resultType = new TypeToken<List<Integer>>(){}.getType(); return gson.fromJson(value, resultType);
(в методе, возвращающем
List<Long>
), тогда как это должно было быть:Type resultType = new TypeToken<List<Long>>(){}.getType();
Есть типобезопасный способ написать это, который бы поднял проблему во время компиляции:
TypeToke<List<Integer>> resultTypeToken = new TypeToken<List<Integer>>() {}; return gson.getAdapter(resultTypeToken).fromJson(value);
Это не компилировалось бы, потому что тип оператора return несовместим с типом return метода.
Возможно, стоит поискать другие вхождения
fromJson
, чтобы вы могли перенести их и посмотреть, есть ли другие проблемы, которые вы еще не нашли!
Вы смотрите на неправильные переменные. Экземпляр ClassDao находится ниже, вы можете увидеть "{Long@6495} "1". Но целое число "1", которое вы распространяете, является элементом ClassIds, который опущен в вашем коде. Вы уверены, что ClassIds-это List (), при добавлении элемента вы должны сделать classIds.добавить (новый длинный(1)).