Есть ли элегантный способ конвертировать Список <Double>в Список <Number>? - PullRequest
2 голосов
/ 07 марта 2012

У меня есть функция, аргументы которой:

 myFn(String, List<Number>, List<Number>)

Вызывающая функция имеет два объекта List, которые я хочу использовать в качестве второго и третьего аргумента функции. Я получаю ошибку компиляции:

The method myFn(String, List<Number>, List<Number>) in the type MyLib is not applicable for the arguments (String, List<Double>, List<Double>)

Есть ли простой способ преодолеть это? Есть ли простой способ превратить список Double в список чисел?

Ответы [ 6 ]

9 голосов
/ 07 марта 2012

Вы не можете привести List<Double> к List<Number>, потому что следующий код сломает ваш List<Double>

List<Double> list = new List<Double>();
List<Number> list1 = list; // This does not work
list1.add(new Integer(0));
Double d = list.get(0);// Hu-hoh you received an Integer, not a Double!!
List<? extends Number> list2 = list; // This does work

Что вы могли бы сделать, это изменить

myFn(String, List<Number>, List<Number>)

до

myFn(String, List<? extends Number>, List<? extends Number>)
4 голосов
/ 07 марта 2012

измените определение myFn на <T extends Number> myFn(String, List<T>, List<T>, Class<T> type), и вы можете назвать его как myFn(String, List<Double>, List<Double>, Double.class)

1 голос
/ 07 марта 2012

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

List<Number> unmodifiableView = Collections.unmodifiableList(doubleList);

, который работает в постоянном времени и возвращает представление. Он абсолютно безопасен для типов, эффективен и легален - если вы знаете, что список не будет изменен.

1 голос
/ 07 марта 2012

Вы не можете разыгрывать Коллекции, подобные этой. Это руководство по Java дает вам полное объяснение.

В качестве решения, когда вы вызываете метод, просто создайте новый список с двойным списком в качестве параметра:

List<Double> doubleList = new ArrayList<Double>();

myFn(new ArrayList<Number>(doubleList));
1 голос
/ 07 марта 2012

Вы можете использовать

myFn(String, List<? extends Number>, List<? extends Number>) 

или вызовите вашу функцию с помощью

myFn(String, (List) list1, (List) list2); // produces a warning. 
1 голос
/ 07 марта 2012

Если вы не можете изменить метод myFn, то читерство - вариант:

private <returntype> myFnAdapter(String s , List<Double> l1Double, List<Double> l2Double) {

  // the following lines do create warnings
  // it's safe, because all list items always extend Number.
  List l1TypeErased = l1Double; 
  List<Number> l1Number = l1TypeErased;

  List l2TypeErased = l2Double;
  List<Number> l2Number = l2TypeErased;

  return myFn(s, l1Number, l2Number);
}

Вы должны увидеть некоторые предупреждения, вот и все.Но мы знаем, что получаем списки Double с и что все элементы этих списков расширяются Number, поэтому это не вызовет проблем во время выполнения.Просто добавьте комментарий, чтобы объяснить тип стирания.Это дешевле, чем копировать все значения в новые списки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...