Не удается преобразовать значение из списка в i-й позиции в long

#java #for-loop #collections

#java #для цикла #Коллекции

Вопрос:

Может быть, это очень просто, но я много борюсь с часами. У меня есть список Long, в котором содержится около 100 значений. Я должен перебрать этот список и должен получить значение в i-й позиции в переменной Long.

 List<Long> dmrIds = (List<Long>)q.getResultList();
  

это мой список, который извлекает данные из базы данных. Я использую цикл for

 for(int i=0;i<dmrIds.size();i  ){
   Long dmrId = dmrIds.get(i).longValue();
   ..........
}
  

Когда я пытаюсь преобразовать в Long, он выдает:

 `java.math.bigDecimal` can't be converted into `java.lang.Long`
  

Я не могу его взломать. Пожалуйста, помогите.

Комментарии:

1. Для меня работает как шарм. Вы уверены, что это то место, где возникает ошибка?

2. Очевидно, что ваш список содержит BigDecimal s. Если есть ошибка, она в q.getResultList() .

3. @Smutje .. Да. Я уверен, что строка вызывает ошибку. Я проверил, установив точки останова

Ответ №1:

Даже если вы преобразуете результат из q.getResultList() в List<Long> , это приведение на самом деле не проверяет, что это List<Long> … потому что во время выполнения это действительно просто List . (Это связано со стиранием типа в Java generics.)

Похоже, что на самом деле это List<BigDecimal> … так что либо вам нужно изменить то, что getResultList() делает, или вам нужно обработать тот факт, что это List<BigDecimal> и иметь дело со BigDecimal значениями.

Вы можете проверить это, выполнив итерацию по каждому элементу и просто распечатав тип:

 List<?> results = (List<?>) q.getResultList();
for (Object result : results) {
     System.out.println(result.getClass());
}
  

Или посмотрите на это в отладчике, конечно.

Чтобы получить все значения как long , вам просто нужно вызвать longValue() :

 List<BigDecimal> results = (List<BigDecimal>) q.getResultList();
for (int i = 0; i < results.size(); i  ) {
    long result = results.get(i).longValue();
    // ...
}
  

(Если вам на самом деле не нужен индекс, я бы предложил использовать расширенный цикл for вместо явного получения каждого элемента по индексу.)

Комментарии:

1. Skeet-> На самом деле мне нужно преобразовать его в long, поскольку мне нужно передать значение long в зависимую систему моего проекта. Это приложение принимает только длинное значение. Итак, есть ли способ преобразовать значение?

2. @SanjayMalhotra: Да, вы можете вызвать BigDecimal.longValue . Но на данный момент вы фактически пытаетесь привести Long к BigDecimal , и это не работает.

Ответ №2:

Хотя кажется, что ваш список содержит BigDecimal записи в отличие от Long записей, на самом деле есть несколько способов получить интересующие вас long данные.

Во-первых, вы можете преобразовать результат в List<BigDecimal> , но это похоже на то, что вы лишаете дженерики одного из основных преимуществ — вам действительно не нужно приводить все так часто. Хуже того, это приводит к несколько нечитаемому и пугающе выглядящему коду.

Если это действительно возвращает List<BigDecimal> , то простое получение этого значения не было бы концом света. Но вам придется выполнять преобразование самостоятельно в цикле, используя longValue .

Другой альтернативой является принятие списка чего-то, что расширяется Number вместо этого, что может быть более чистым вариантом. Вы все равно будете извлекать его longValue в любом случае, и Number для этого уже есть метод.

BigDecimal является подклассом Number , поэтому это объявление является законным:

 List<? extends Number> results = q.getResultList();
for(Number number : results) {
    long dmrId = number.longValue();
    // other processing
}
  

? extends Number является подстановочным знаком с ограничением сверху; это позволит вам создать список, содержащий все, что является подклассом Number , который, опять же, включает BigDecimal .

Ответ №3:

На основе сообщения об исключении результат выборки возвращает объект java.math.BigDecimal. BigDecimal больше, чем java.lang.Длинный и используется для огромных чисел.

 List<LBigDecimal> results = (List<LBigDecimal>)q.getResultList();
for(BigDecimal big : results) {
    // do something
    big.add(new BigDecimal(1L);
}
  

Комментарии:

1. @Vahid-> здесь мы снова добавляем к объекту bigdecimal. Я хочу это в Long value.

2. Например, я вызвал add, я хочу сказать, что класс BigDecimal имеет больше методов для некоторых операций. 🙂