2013-05-25 1 views
3

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

Collection<MiClase> collection1 = new ArrayList<MiClase>; 
Collection<String> collection2 = new ArrayList<String>; 
// I currently do this 
for (MiClase c : collection1){ 
    collection2.add(c.nombre()); // nombre() returns String 
} 

Есть ли что-нибудь, чтобы сделать его короче?

// I want something like 
collection2.addAll(collection1, MiClase.nombre); 

спасибо !!!

+0

Если что-то подобное существовало, было бы в JavaDocs, и это не :(. Поэтому, к сожалению, вы застряли в том, что делаете сейчас, если не хотите взять комментарий Дукелинга об отражении. – greedybuddha

ответ

5

Не существует встроенной функции java, которая делает это¹. Вы можете использовать гуава «Collections2#transform(collection, function)»

Итак, ваш код будет выглядеть примерно так

// nombres = collections2, miClasses = collection1 
nombres.addAll(Collections2.transform(miClasses, new Function() { 
    @Override 
    public String apply (MiClasse miClasse) { 
     return miClasse.nombre(); 
    } 
})); 

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

EDIT

1 - Как отметил A.R.S., не встроенный, прежде чем выражение Java 8 лямбда и улучшение сбора API. Связь с некоторыми прохладными примерами: http://www.javabeat.net/2012/05/enhanced-collections-api-in-java-8-supports-lambda-expressions/

+1

Тот факт, что Java не поддерживает лямбда-выражения (или, по крайней мере, не будет до тех пор, пока Java 8) не сделает это очень громоздким, так как нам нужно расширить/создать экземпляр класса только для одного метода (это похоже на подделку лямбда-функций через анонимные классы). Я бы посоветовал также придерживаться петли, +1 в любом случае. – arshajii

+0

@ A.R.S. Да, полностью согласен.Я ищу Java 8 с лямбда-выражениями и улучшенным боксом/распаковкой JVM. –

+0

Я хочу этого! поэтому мне нужно подождать до новой java :( – leftsync

2

больше для полноты, чем все остальное ...

Вы могли бы написать метод, чтобы сделать это с помощью reflection:

static <A,B> void addAll(Collection<B> dest, Collection<A> source, String methodName) 
     throws IllegalAccessException, InvocationTargetException, NoSuchMethodException 
{ 
    for (A a: source) 
    { 
    // can optimize this to only get method once if all objects have same type 
    Method m = a.getClass().getMethod(methodName); 
    dest.add((B)m.invoke(a)); 
    } 
} 

Usage/пример:

ArrayList<String> s = new ArrayList<String>(); 
List<Integer> i = Arrays.asList(1,2,3); 
addAll(s, i, "toString"); 
System.out.println(s); 

Вы также можете добавить параметры метода, если хотите.

Test.

Почему я >> НЕ < < рекомендовать его:

Если метания 3 исключения не вы беспокоитесь еще ... (конечно, вы можете try - catch, а во избежание исключения вообще)

несколько точек (человека) отказа: (все они будут отображаться как ошибки во время выполнения, но время компиляции предпочтительными являются ошибки)

  • метод п АМА орфографическая ошибки
  • метод даже не существует
  • Метод не возвращает объект типа B
Смежные вопросы