2017-05-13 5 views
8

मैं एक वर्ग IndexEntry जो इस तरह दिखता है:मै मैप में सबसे लगातार शब्द कैसे प्राप्त करूं और जावा 8 स्ट्रीम का उपयोग करके घटना की इसी आवृत्ति को कैसे प्राप्त किया जाए?

public class IndexEntry implements Comparable<IndexEntry> 
{ 
    private String word; 
    private int frequency; 
    private int documentId; 
    ... 
    //Simple getters for all properties 
    public int getFrequency() 
    { 
     return frequency; 
    } 
    ... 
} 

मैं एक अमरूद SortedSetMultimap (जो कुंजी प्रति एक से अधिक मान के लिए अनुमति देता है) जहाँ मैं कुछ IndexEntry रों करने के लिए एक String शब्द मानचित्रण हूँ में इस वर्ग की वस्तुओं के भंडारण कर रहा हूँ । दृश्यों के पीछे, यह प्रत्येक शब्द को SortedSet<IndexEntry> पर मानचित्र करता है।

मैं दस्तावेजों के अंदर दस्तावेजों और उनकी घटना आवृत्तियों के शब्दों की एक अनुक्रमित संरचना को लागू करने की कोशिश कर रहा हूं।

मुझे पता है कि सबसे आम शब्द के को कैसे प्राप्त करें, लेकिन मुझे यह शब्द नहीं मिल रहा है। क्योंकि वे वास्तव में उपयोगी प्रतीत

public int mostFrequentWordFrequency() 
{ 
    return entries 
      .keySet() 
      .stream() 
      .map(this::totalFrequencyOfWord) 
      .max(Comparator.naturalOrder()).orElse(0); 
} 

public int totalFrequencyOfWord(String word) 
{ 
    return getEntriesOfWord(word) 
      .stream() 
      .mapToInt(IndexEntry::getFrequency) 
      .sum(); 
} 

public SortedSet<IndexEntry> getEntriesOfWord(String word) 
{ 
    return entries.get(word); 
} 

मैं जावा 8 सुविधाओं जानने की कोशिश कर रहा हूँ:

यहाँ है कि मैं क्या, सबसे आम शब्द है, जहां entriesSortedSetMultimap है की गणना प्राप्त करने में सहायक तरीकों के साथ साथ है । हालांकि, मुझे लगता है कि जिस तरह से मैं चाहता हूं स्ट्रीम स्ट्रीम नहीं कर सकता। मैं स्ट्रीम के अंत में शब्द और इसकी आवृत्ति दोनों को प्राप्त करने में सक्षम होना चाहता हूं, लेकिन यदि मेरे पास शब्द है, तो मैं उस शब्द की कुल घटनाओं को आसानी से प्राप्त कर सकता हूं।

वर्तमान में, मैं Stream<SortedSet<IndexEntry>> के साथ समाप्त रहता हूं, जिसे मैं कुछ भी नहीं कर सकता। मुझे नहीं पता कि आवृत्तियों के बिना सबसे लगातार शब्द कैसे प्राप्त किया जाए, लेकिन यदि मेरे पास आवृत्ति है, तो मैं इसी शब्द का ट्रैक नहीं रख सकता। मैंने दोनों को स्टोर करने के लिए WordFrequencyPair पीओजेओ कक्षा बनाने की कोशिश की, लेकिन फिर मेरे पास Stream<SortedSet<WordFrequencyPair>> था, और मैं यह समझ नहीं पाया कि इसे किसी चीज़ में कैसे मैप करना है।

मुझे क्या याद आ रही है?

उत्तर

6

मुझे लगता है कि नहीं बल्कि word से TreeMultimap की कुंजी के रूप में उपयोग करने के लिए documentId एक बेहतर डिजाइन होगा:

import com.google.common.collect.*; 

public class Main { 

    TreeMultimap<Integer, IndexEntry> entries = TreeMultimap.<Integer, IndexEntry>create(Ordering.arbitrary(), Ordering.natural().reverse()); 

    public static void main(String[] args) { 
     // Add elements to `entries` 

     // Get the most frequent word in document #1 
     String mostFrequentWord = entries.get(1).first().getWord(); 
    } 

} 

class IndexEntry implements Comparable<IndexEntry> { 

    private String word; 

    private int frequency; 

    private int documentId; 

    public String getWord() { 
     return word; 
    } 

    public int getFrequency() { 
     return frequency; 
    } 

    public int getDocumentId() { 
     return documentId; 
    } 

    @Override 
    public int compareTo(IndexEntry i) { 
     return Integer.compare(frequency, i.frequency); 
    } 

} 

फिर आप तरीकों कि आप निम्नलिखित के साथ पहले था लागू कर सकते हैं:

JDK द्वारा
public static int totalFrequencyOfWord(String word) { 
    return entries.values() 
        .stream() 
        .filter(i -> word.equals(i.getWord())) 
        .mapToInt(IndexEntry::getFrequency) 
        .sum(); 
} 

/** 
* This method iterates through the values of the {@link TreeMultimap}, 
* searching for {@link IndexEntry} objects which have their {@code word} 
* field equal to the parameter, word. 
* 
* @param word 
*  The word to search for in every document. 
* @return 
*  A {@link List<Pair<Integer, Integer>>} where each {@link Pair<>} 
*  will hold the document's ID as its first element and the frequency 
*  of the word in the document as its second element. 
* 
* Note that the {@link Pair} object is defined in javafx.util.Pair 
*/ 
public static List<Pair<Integer, Integer>> totalWordUses(String word) { 
    return entries.values() 
        .stream() 
        .filter(i -> word.equals(i.getWord())) 
        .map(i -> new Pair<>(i.getDocumentId(), i.getFrequency())) 
        .collect(Collectors.toList()); 
} 
+0

तो करके, लगता है कि मैं दस्तावेज़ आईडी कि किसी दिए गए शब्द, में मौजूद था जो दस्तावेज़ में घटनाओं की संख्या के साथ-साथ को देखने के लिए की जरूरत है। आपके उदाहरण में, मैं ऐसा करने के बारे में कैसे जाऊं? –

+0

मैं ऐसा करने के लिए एक विधि लिखूंगा और समझाऊंगा कि यह कैसे काम करता है –

+0

मुझे लगता है कि यह काम करेगा। धन्यवाद! –

0

मूल निवासी समाधान:

entries.keySet().stream() 
    .collect(groupingBy(IndexEntry::getWord, summingInt(IndexEntry::getFrequency))) 
    .values().stream().max(Comparator.naturalOrder()).orElse(0L); 

या StreamEx

StreamEx.of(entries.keySet()) 
    .groupingBy(IndexEntry::getWord, summingInt(IndexEntry::getFrequency)) 
    .values().stream().max(Comparator.naturalOrder()).orElse(0L); 
संबंधित मुद्दे

 संबंधित मुद्दे