2016-07-27 1 views
2

У меня есть функция с параметром Object. Этот объект может будет коллекцией в самом общем смысле это возможно: это может быть список, картой, итерация и т.д., в этом случае я хочу, чтобы обработать каждый элемент, принадлежащим к нему:Как получить поток из общей коллекции?

public void f(Object o) { 
    if (o instanceof SOMECLASSORINTERFACE<?>) { 
     Stream.of(o).map(..)...; 
    } else { 
     // o is scalar 
     ... 
    } 
} 

код выше не работает: Stream.of() не разбивает мой объект на его элементы на поток, а выводит только один элемент, объект o сам.

Я не могу использовать o.stream().map..., потому что o является слишком общим и может не иметь метода stream.

Отливка o на Collection не работает. Кроме того, проверка Collection членства, вероятно не правильно делать ...

Так как я могу получить поток из родового коллекции?

+2

Объект не является родовой коллекцией она родовое все, что вам нужно будет сделать отливку или использовать, например, Итерабельный вместо объекта. –

ответ

1

Решение, которое я в настоящее время является тестирование для обоих Iterable (см Convert Iterable to Stream using Java 8 JDK) и Map членство:

public void f(Object o) { 
    if (o instanceof Iterable<?>) { 
     StreamSupport.stream(((Iterable<?>) o).spliterator(), false).map(e -> ... 
    } else if (o instanceof Map<?,?>) { 
     ((Map<?,?>) o).entrySet().stream().map(e -> ... 
    } else { 
     // scalar object 
     ... 
    } 
} 
1

Если ваш Object является Collection<?>, и вы хотите, чтобы относиться к нему как Collection<?>, затем бросил его.

public void f(Object o) { 
    if (o instanceof Collection<?>) { 
     Collection<?> c = (Collection<?>)o; 
     c.stream().map(...).forEach(System.out::println); 
    } else { 
     System.out.println(o); 
    } 
} 
+0

Мой «объект» - это «объект», он может быть или не быть «сборником». – sebnukem

+1

@sebnukem Вот что 'if (o instanceof Collection ) {...' для. Вы только бросаете его, если это 'Collection '. – bradimus

+0

Да, но он не охватывает все возможные типы коллекций, например карты. «Карта» - это не «Коллекция». – sebnukem

3

Правильным бы, конечно, не иметь функцию, которая принимает Object, но использовать функцию oberloading и думать о том, что вы, возможно, могли бы взять с собой:

  • Collection<T> - это действительно имеет .stream() и охватывает большинство случаев, таких как List, Set и т.д.
  • Map<K,V> не покрывается Collection<T>, но его .entrySet(), .keySet() и т.д. будет.
  • Iterable<T> пришлось бы обрабатывать отдельно с помощью StreamSupport.stream(((Iterable<?>) o).spliterator(), false), как вы уже упоминали.

Так создать три функции для трех случаев, указанных выше, и вы будете, вероятно, будет в порядке:

public <T> void f(Stream<T> s) { 
    s.map(..) 
     .forEach(System.out::println); 
} 

public void f(Collection<?> o) { 
    f(o.stream()); 
} 

public void f(Map<?,?> m) { 
    f(m.entrySet().stream()); 
} 

public void f(Iterable<?> i) { 
    f(StreamSupport.stream(i.spliterator(), false)); 
} 

public void f(Object o) { 
    // for the cases none of the others match 
    System.out.println(o); 
} 
+0

Да, это решение, которое у меня есть. Спасибо. – sebnukem

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