Java-массивы и итерационная реализация foreach - PullRequest
2 голосов
/ 29 сентября 2011

Есть ли какой-нибудь интерфейс, который позволит выполнять итерацию массивов и java.util.Lists?

Видя, как цикл for-each может повторять и то и другое, мне кажется, должна быть какая-то база 'итерируемый », который просматривается в обоих случаях.

Итак, я могу установить параметр метода, который принимает либо Foo [], либо List?

У нас есть много старого кода (который мы выигралине будет обновляться), который вызывает несколько низкоуровневых методов (которые я хотел бы обновить), ожидающих массивы.

Наш новый код преобразуется из списков (особенно ArrayLists большую часть времени) в массивыиспользуя метод ListArray, и я хотел бы пропустить этот шаг.

Я видел этот пост, в котором показана реализация, но я не уверен, как это можетhelp.

Можно ли это сделать?

Ответы [ 4 ]

4 голосов
/ 29 сентября 2011

Нет, спецификация языка явно вызывает массивы отдельно.Массивы не реализуют Iterable<T>, который является «нормальным» интерфейсом, используемым расширенным циклом for, отличным от массивов.Из раздела 14.14.2 JLS :

расширенный оператор for имеет вид:

 EnhancedForStatement:
       for ( VariableModifiers Type Identifier: Expression) Statement

Выражение mustлибо имеют тип Iterable, либо он должен иметь тип массива ( §10.1 ), либо возникает ошибка времени компиляции.

Затем эти два случая обрабатываются отдельно.

Конвертировать массивы в списки, конечно, легко - но, похоже, вам нужно сделать это наоборот.На самом деле не существует «приятного» способа сделать это - и для создания массива, конечно же, нужно копировать все.

Сколько нужно было бы преобразовать, по крайней мере, наиболее часто используемые биты API для использования списков?

Конечно, вы можете писать перегрузки методов, например,

public void foo(String[] array)
{
    foo(Arrays.asList(array));
}

public void foo(List<String> list)
{
    // Use the list
}

... но выполнение этого для вашего старого кода все равно потребует работы, поскольку реальная реализация в терминах списка,не массив.

1 голос
/ 29 сентября 2011

Java могла бы сделать Foo[] подтипом Iterable<Foo>;к сожалению, это не будет работать на примитивных массивах, потому что Java не поддерживает аргументы примитивного типа, поэтому у нас нет такой тонкости.

0 голосов
/ 29 сентября 2011

Нет такого общего интерфейса, Array не реализует Iterable.

Что вы можете сделать, это перегрузить ваш метод:

public void mymethod(String ... strings) {
   mymethod(Arrays.asList(strings));
}

public void mymethod(List<String> strings) {
   // do what you need
}
0 голосов
/ 29 сентября 2011

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

Одна вещь, которую вы можете сделать, это перегрузить ваши методы:

public void foo(MyClass[] stuff) {
    foo(Arrays.asList(stuff));
}

public void foo(Collection<MyClass> stuff) {
    // stuff
}

Или наоборот:

public void foo(MyClass[] stuff) {
    // stuff
}

public void foo(Collection<MyClass> stuff) {
    foo(stuff.toArray(new MyClass[stuff.size()]));
}
...