2014-10-15 5 views
1

Я пытаюсь переписать известный пример классификации текстов Спарк в (http://chimpler.wordpress.com/2014/06/11/classifiying-documents-using-naive-bayes-on-apache-spark-mllib/) на Java 8.операция groupingBy в Java-8

У меня есть проблема - в этом коде я делаю некоторые препараты данных для получение idfs всех слов во всех файлах:

termDocsRdd.collect().stream().flatMap(doc -> doc.getTerms().stream() 
           .map(term -> new ImmutableMap.Builder<String, String>() 
           .put(doc.getName(),term) 
           .build())).distinct()   

И я застрял в операции groupBy. (Мне нужно группировать это по срокам, поэтому каждый термин должен быть ключом, а значение должно быть последовательностью документов). В Scala эта операция выглядит очень просто - .groupBy (_._ 2). Но как я могу это сделать на Java?

Я пытался написать что-то вроде:

.groupingBy(term -> term, mapping((Document) d -> d.getDocNameContainsTerm(term), toList())); 

но это неправильно ...

Кто-нибудь знает, как писать в Java?

спасибо.

ответ

2

Если я вас правильно понял, вы хотите сделать что-то вроде этого:

(import static java.util.stream.Collectors.*;)

Map<Term, Set<Document>> collect = termDocsRdd.collect().stream().flatMap(
doc -> doc.getTerms().stream().map(term -> new AbstractMap.SimpleEntry<>(doc, term))) 
.collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toSet()))); 

Использование Map.Entry/AbstractMap.SimpleEntry связано с отсутствием стандартного Pair<K,V> класса в Java -8. Map.Entry реализации могут выполнять эту роль, но за счет наличия неинтуитивных и многословных имен типов и методов (в отношении выполнения функции Pair).


Если вы используете текущую версию Eclipse (я тестировал с LunaSR1 20140925) с его ограниченным умозаключением типа, вы должны помочь компилятору немного:

Map<Term, Set<Document>> collect = termDocsRdd.collect().stream().flatMap(
doc -> doc.getTerms().stream().<Map.Entry<Document,Term>>map(term -> new AbstractMap.SimpleEntry<>(doc, term))) 
.collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toSet()))); 
+0

Спасибо Людей за ответ! Но когда я пытаюсь использовать ваш код в Eclipse - я получил ошибку компиляции - ** Невозможно выполнить сопоставление типов: невозможно преобразовать из ** 'Map >' ** to ** 'Map >' Естественно , если я изменю «Map > 'to' Map > 'Ошибка возврата Eclipse, этот тип Map.Entry не имеет getKey() и getValue(). Я нашел очень похожий пример этой ситуации [здесь] (http://stackoverflow.com/questions/23423078/java-8-grouping-by-from-one-to-many), а Lukasz Wiktor получил ту же ошибку в Eclipse , Не могли бы вы сказать мне, что случилось? Спасибо – dimson

+0

Боюсь, для поддержки Java-8 Eclipse по-прежнему требуется больше времени, чтобы созреть. – Holger

+0

Спасибо, человек! Я попробую другую IDE. – dimson

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