2013-04-05 2 views
0

У меня есть Guava Functions как Function<String,Set<String>>. Использование с FluentIterable.transform() приводит к FluentIterable<Set<String>>, однако мне нужен FluentIterable<String>. Поэтому теперь моя идея будет заключаться в подклассе FluentIterable<E> и добавлении нового метода transform2(), который просто объединяет все в одну коллекцию, прежде чем возвращать ее.Автоматически объединить несколько коллекций в один

оригинальный метод преобразования выглядит следующим образом:

public final <T> FluentIterable<T> transform(Function<? super E, T> function) { 
    return from(Iterables.transform(iterable, function)); 
} 

Я думал, что-то вроде этого для моего подкласса и transform2() метода:

public abstract class FluentIterable2<E> extends FluentIterable<E> 
{  
    public final <T> FluentIterable<T> transform2(Function<? super E, Collection<T>> function) { 
     // (PROBLEM 1) Eclipse complains: The field FluentIterable<E>.iterable is not visible 
     Iterable<Collection<T>> iterables = Iterables.transform(iterable, function); 

     // (PROBLEM 2) Collection<T> merged = new Collection<T>(); // I need a container/collection - which one? 
     for(Collection<T> iterable : iterables) 
     { 
      // merged.addAll(iterable); 
     } 

     // return from(merged); 
    } 
} 

В настоящее время у меня есть две проблемы с моим новым подклассом, отмеченный выше с PROBLEM 1 и PROBLEM 2

  • ПРОБЛЕМА 1: Итерируемое поле в исходном классе FluentIterable является частным - что я могу сделать по этому поводу? Могу ли я создать новое личное поле с тем же именем в моем подклассе, будет ли это тогда ОК? Как насчет методов в моем подклассе, которые называют super.someMethod(), который использует это поле? Будут ли они затем использовать поле суперкласса, который, вероятно, имеет другое значение?

  • ПРОБЛЕМА 2: Мне нужна общая коллекция, в которой я могу объединить содержимое нескольких коллекций, но коллекции - это интерфейс, поэтому я не могу его создать. Итак, какой класс я могу использовать там?

Было бы приемлемо, если решение работает только с наборами, хотя я бы предпочел решение, которое работает с наборами и списками.

Спасибо за любой намек на это!

ответ

6

FluentIterable.transformAndConcat(stringToSetFunction) Не работает ли ваш прецедент?

+0

Это, кажется, делает точные, что я искал, хотя даже сейчас я не понимаю документацию для этого !? –

+0

В какой части документации вы не понимаете? Если вы сообщите нам, возможно, мы сможем улучшить документы. –

+0

Это абстрактное, на мой взгляд, когда я читаю имя метода или javadoc «возвращает беглое итерабельное с конкатенированной комбинацией результатов», я думаю о конкатенированных строках. Хорошо, теперь я замечаю, что если вы думаете о конкатенации Iterables, это действительно подходит, может быть, добавить sth. например «это означает, что коллекции, возвращаемые функцией, объединяются в одну коллекцию» или sth. как это, но, вероятно, это действительно моя ошибка ;-) –

3

Почему подкласс FluentIterable только для этого? Вам просто нужен простой цикл:

Set<String> union = Sets.newHashSet(); 
for (Set<String> set : fluentIterableOfSets) { 
    union.addAll(set); 
} 
+0

Ну, я не всегда хочу писать этот цикл, также хочу объединить несколько вызовов методов (поэтому я использую FluentIterable), но следующие функции преобразования, которые я использую, ожидают только коллекции, а не коллекции коллекций. –

3

Используйте FluentIterable.transformAndConcat(f), где f - это функция, сопоставляющая элемент с каким-либо итерабельным типом элемента.

В вашем случае, скажем, ваш Function<String, Set<String>> называется TOKENIZE, а ваш начальный номер Iterable<String> называется LINES.

Затем, чтобы получить Set<String> держит все различные маркеры в ЛИНИЙ, сделайте следующее:

Iterable<String> LINES = ...; 
Function<String, Set<String>> TOKENIZE = ...; 
Set<String> TOKENS = FluentIterable.from(LINES) 
    .transformAndConcat(TOKENIZE) 
    .toSet(); 

Но внимательно рассмотреть ответ JB Nizet в. Попробуйте в обоих направлениях и посмотрите, какая из них работает лучше.

+0

Благодарю вас за полный пример, приятный для архива. Но почему следует внимательно рассмотреть ответ Дж. Б. Низета? Какую возможную проблему вы видите с прямым способом Guava? –

+1

Прочтите раздел «Предостережения» этой страницы для получения полного ответа: https://code.google.com/p/guava-libraries/wiki/FunctionalExplained –

Смежные вопросы