程式扎記: [ Java 套件 ] BabelINet - How to query BabelNet programmatically (v3.7)

標籤

2016年12月9日 星期五

[ Java 套件 ] BabelINet - How to query BabelNet programmatically (v3.7)

Source From Here
Java API
The BabelNet Java API requires JRE 1.7 or above. Since the BabelNet 3.5 release, any data retrieved with the API is by default only in the search language. Should one want to retrieve other languages, it is possible to use the specific parameter Collection filterLangs present in the most important API methods. It is not possible to retrieve more than three languages other than the search language. For more details see this example.

Here you can access the javadoc for the API. To work with the Java API, unpack the zip file with:
# unzip BabelNet-API-3.7.zip

The file is available the download section.

Configuration
The first important step is the configuration of the properties files located inside the BabelNet API folder. For instance, assuming you received by email the following key (see key & limits): abcdefghilmnopqrstuvz
Then Edit the babelnet.var.properties files inside BabelNet-API-3.7/config/ and add the following line into babelnet.var.properties:
babelnet.key=abcdefghilmnopqrstuvz

Running the BabelNet demo
Now, you can test that everything works by below sample code:
- BabelNetDemo.groovy
  1. package demo  
  2.   
  3. import it.uniroma1.lcl.babelnet.BabelImage;  
  4. import it.uniroma1.lcl.babelnet.BabelNet;  
  5. import it.uniroma1.lcl.babelnet.BabelNetUtils;  
  6. import it.uniroma1.lcl.babelnet.BabelSense;  
  7. import it.uniroma1.lcl.babelnet.BabelSenseComparator;  
  8. import it.uniroma1.lcl.babelnet.BabelSynset;  
  9. import it.uniroma1.lcl.babelnet.BabelSynsetComparator;  
  10. import it.uniroma1.lcl.babelnet.BabelSynsetID;  
  11. import it.uniroma1.lcl.babelnet.BabelSynsetIDRelation;  
  12. import it.uniroma1.lcl.babelnet.InvalidBabelSynsetIDException;  
  13. import it.uniroma1.lcl.babelnet.data.BabelGloss;  
  14. import it.uniroma1.lcl.babelnet.data.BabelPOS;  
  15. import it.uniroma1.lcl.babelnet.data.BabelSenseSource;  
  16. import it.uniroma1.lcl.jlt.util.Language;  
  17. import it.uniroma1.lcl.jlt.util.ScoredItem;  
  18.   
  19. import java.io.IOException;  
  20. import java.util.Arrays;  
  21. import java.util.Collections;  
  22. import java.util.List;  
  23.   
  24. def mainTest() throws IOException  
  25. {  
  26.     BabelNet bn = BabelNet.getInstance();  
  27.     String word = "bank";  
  28.     System.out.println("SYNSETS WITH English word: \""+word+"\"");  
  29.     List synsets = bn.getSynsets(word, Language.EN);  
  30.     Collections.sort(synsets, new BabelSynsetComparator(word));  
  31.     for (BabelSynset synset : synsets)  
  32.     {  
  33.         // synset.getId()   
  34.         printf(String.format('=>(%s)SOURCE: %s;TYPE: %s; WN SYNSET: %s \n\tMAIN LEMMA: %s \n',   
  35.                             synset.getId(), synset.getSynsetSource(), synset.getSynsetType(), synset.getWordNetOffsets(),  
  36.                             synset.getMainSense(Language.EN)))  
  37.         printf("\t=== IMAGES ===:\n")  
  38.         for(Object o:synset.getImages())   
  39.         {  
  40.             try  
  41.             {  
  42.                 System.out.printf(String.format('\t%s\n', o)) // it.uniroma1.lcl.babelnet.BabelImage  
  43.             }  
  44.             catch(Exception e){}  
  45.         }  
  46.         printf("\t=== CATEGORY ===:\n")  
  47.         for(Object o:synset.getCategories())  
  48.         {  
  49.             try{  
  50.                 printf(String.format("\t$o\n"))  
  51.             }  
  52.             catch(Exception e){}  
  53.         }  
  54.         printf("\t===SENSES (Italian) ===: {\n")  
  55.         for (BabelSense sense : synset.getSenses(Language.IT))  
  56.         {  
  57.             try{  
  58.                 printf(String.format("\t%s (%s)\n", sense.toString(), sense.getPronunciations()))  
  59.             } catch(Exception e){printf("\t%s\n", e.getMessage())}  
  60.         }  
  61.         System.out.println("}")   
  62.         System.out.println()  
  63.     }  
  64. }  
  65.   
  66. try  
  67. {  
  68.     BabelNet bn = BabelNet.getInstance();     
  69.     System.out.println("=== DEMO ===");  
  70.     BabelSynset  synset = bn.getSynset(new BabelSynsetID("bn:03083790n"));  
  71.     System.out.println("Welcome on "+synset.getMainSense(Language.EN).getLemma().replace("_"" "));  
  72.     System.out.println(synset.getMainGloss(Language.EN).getGloss());  
  73.     mainTest()  
  74. }  
  75. catch(Exception e)  
  76. {  
  77.     e.printStackTrace()  
  78. }  
Execution result look like:


If you replace the word to "銀行" and change Language.EN to Language.ZH (Enum Language) and execute above sample code again, you will get:


Explain Code
Let's now look at the main classes in the BabelNet API. For more details, see the API javadoc.

Main classes
The main classes of BabelNet are:
BabelNet (the entry point to BabelNet)
BabelSynset (a concept or named entity identified by a set of multilingual lexicalizations (each being a BabelSense))
BabelSense (a lexicalization of a given concept (BabelSynset))

BabelNet
The BabelNet class is used as the entry point to access all the content available in BabelNet. The class is implemented through the Singleton pattern, where we restrict the instantiation of the BabelNet class to one object. You can obtain a reference to the only instance of the BabelNet class with the following line:
  1. BabelNet bn = BabelNet.getInstance();  
Now you are ready to use the BabelNet object to work with the BabelNet API.

BabelSynset
BabelSynset is a set of multilingual lexicalizations that are synonyms expressing a given concept or named entity. For instance, the synset for car in the motorcar sense looks like this. After creating the BabelNet object which we call bn, we can use its methods to retrieve one or many BabelSynset objects. For instance, to retrieve all the synsets containing car we can call the BabelNet#getSynset method:
  1. // Given a word in a certain language,  
  2. // returns the concepts (`BabelSynsets`) denoted by the word.  
  3. List byl = bn.getSynsets("car", Language.EN);  
We can also specify which of the parts of speech we are interested in and obtain only synsets for the specified part of speech. In the following example we retrieve all the verbal synsets containing the English lexicalization run:
  1. // Given a word in a certain language and pos (part of speech),  
  2. // returns the concepts denoted by the word.  
  3. List byl = bn.getSynsets("run", Language.EN, BabelPOS.VERB);  
The full list of BabelPOS values is:
  1. public enum BabelPOS  
  2. {  
  3. NOUN,  
  4. ADJECTIVE,  
  5. VERB,  
  6. ADVERB,  
  7. INTERJECTION,  
  8. PREPOSITION,  
  9. ARTICLE,  
  10. DETERMINER,  
  11. CONJUNCTION,  
  12. PRONOUN;  
  13. }  
However, as of version 3.0, only the open-class (i.e., top 4) parts of speech are available. Due to the nature of BabelNet, a BabelSynset may contain lexicalizations from different sources. You can restrict your search only to your sources of interest. For instance:
  1. // Given a word in a certain language, returns the concepts  
  2. // for the word available in the given sense sources.  
  3. List byl = bn.getSynsets("run", Language.EN, BabelPOS.NOUN, BabelSenseSource.WIKI, BabelSenseSource.OMWIKI);  
The full list of BabelSenseSource is:
  1. public enum BabelSenseSource  
  2. {  
  3.     BABELNET,    // BabelNet senses, not available as of version 3.0  
  4.     WN,          // WordNet senses  
  5.     OMWN,        // Open Multilingual WordNet  
  6.     WONEF,       // WordNet du Francais  
  7.     WIKI,        // Wikipedia page  
  8.     WIKIDIS,     // Wikipedia disambiguation pages  
  9.     WIKIDATA,    // Wikidata senses  
  10.     OMWIKI,      // OmegaWiki senses  
  11.     WIKICAT,     // Wikipedia category, not available as of version 3.0  
  12.     WIKIRED,     // Wikipedia redirections  
  13.     WIKT,        // Wiktionary senses  
  14.     WIKIQU,      // Wikiquote page  
  15.     WIKIQUREDI,  // Wikiquote redirections  
  16.     WIKTLB,      // Wiktionary translation label  
  17.     VERBNET,     // VerbNet senses  
  18.     FRAMENET,    // FrameNet senses  
  19.     MSTERM,      // Microsoft Terminology items  
  20.     GEONM,       // GeoNames items  
  21.     WNTR,        // Translations of WordNet senses  
  22.     WIKITR       // Translations of Wikipedia links  
  23. }  
Each BabelSynset has an ID that univocally identifies the synset and that can be obtained via the BabelSynset#getId method. If we have an ID and want to retrieve the corresponding synset, we can use the overloaded BabelNet#getSynset method. For instance:
  1. // Gets a BabelSynset from a concept identifier (Babel synset ID).  
  2. BabelSynset by = bn.getSynset(new BabelSynsetID("bn:03083790n"));  
which will returns the BabelSynset corresponding to ID bn:03083790n, that is, the synset about BabelNet.

If we want to retrieve the BabelSynset corresponding to a given WordNet 3.0 ID, we can use another overloaded version of the BabelNet#getSynset method:
  1. // Gets the BabelSynsets corresponding to an input WordNet offset.  
  2. BabelSynset by = bn.getSynset(new WordNetSynsetID("wn:06879521n"));  
If we want to retrieve the BabelSynset corresponding to a given WordNet old version ID, we can use another overloaded version of the BabelNet#getSynset method:
  1. // Gets the BabelSynsets corresponding to an input WordNet offset of the version 2.1.  
  2. BabelSynset by = bn.getSynset(new WordNetSynsetID("wn:06303048n", WordNetVersion.WN_21));  
If we want to retrieve the BabelSynset corresponding to a given Wikidata page ID, we can use another overloaded version of the BabelNet#getSynset method:
  1. // Gets the BabelSynsets corresponding to an input Wikidata page ID.  
  2. BabelSynset by = bn.getSynset(new WikidataID("Q4837690"));  
If we want to retrieve the BabelSynset containing a given Wikipedia page title, we can use the method BabelNet#getSynsets:
  1. // Given a Wikipedia title, returns the BabelSynsets which contain it.  
  2. List byl = bn.getSynsets(new WikipediaID("Men in Black (film 1997)", Language.IT, BabelPOS.NOUN));  
BabelSense
BabelSense is a term (either word or multi-word expression) in a given language occurring in a certain BabelSynset. Each occurrence of the same term (e.g., car) in different synsets is therefore a different BabelSense of that term. Now let's look at the methods to retrieve a BabelSense using the bn object we created earlier:
  1. // Returns the senses for the word in a certain language.  
  2. List senses = bn.getSenses("home", Language.EN);  
  3.   
  4. // Returns the senses for the word in a certain language and Part-Of-Speech.  
  5. List senses = bn.getSenses("run", Language.EN, BabelPOS.VERB);  
  6.   
  7. // Returns the senses for the word with the given constraints.  
  8. List senses = bn.getSenses("run", Language.EN, BabelPOS.VERB, BabelSenseSource.WIKI, BabelSenseSource.OMWIKI);  
Once we have a BabelSense, we can go back to the synset it belongs to using the BabelSense#getSynset method:
  1. BabelSynset by = sense.getSynset();  
We can view the BabelSynset as a container of BabelSynset, i.e., the lexicalizations in the various languages contained in the synset that express its concept or named entity.

Some methods of BabelSynset and BabelSense
We are now going into details about important methods of the BabelSynset and BabelSense classes.

Main BabelSynset methods
BabelSynset is composed of various elements which we describe below. Furthermore, a BabelSynset is connected to other BabelSynset objects. The main components of a BabelSynset are objects of the following types:
1. BabelSense (a lexicalization of the concept, see above)
2. BabelPOS (the synset's part of speech)
3. BabelGloss (a definition of the concept in a given language)
4. BabelExample (an example sentence of the meaning expressed by the synset)
5. BabelImage (an image depicting the concept)
6. BabelSynsetIDRelation (an edge semantically connecting the synset to another synset)

Let's take a look at the main methods of a BabelSynset object which we call by. Note: to obtain BabelSynset objects we can also use the above examples.
  1. // Gets a BabelSynset from a concept identifier (Babel synset ID).  
  2. BabelSynset by = bn.getSynset(new BabelSynsetID("bn:03083790n"));  
  3.   
  4. // Most relevant BabelSense to this BabelSynset for a given language.  
  5. BabelSense bs = by.getMainSense(Language.EN);  
  6.   
  7. // Gets the part of speech of this BabelSynset.  
  8. BabelPOS pos = by.getPOS();  
  9.   
  10. // True if the BabelSynset is a key concept  
  11. boolean iskeyConcept = by.isKeyConcept();  
  12.          
  13. // Gets the senses contained in this BabelSynset.  
  14. List senses = by.getSenses();  
  15.   
  16. // Collects all BabelGlosses in the given source for this BabelSynset.  
  17. List glosses = by.getGlosses();  
  18.   
  19. // Collects all BabelExamples for this BabelSynset.  
  20. List examples = by.getExamples();  
  21.   
  22. // Gets the images (BabelImages) of this BabelSynset.  
  23. List images = by.getImages();  
  24.   
  25. // Collects all the edges incident on this BabelSynset.  
  26. List edges = by.getEdges();  
  27.   
  28. // Gets the BabelCategory objects of this BabelSynset.  
  29. List cats = by.getCategories();  
Main BabelSense methods
We now have a look at the BabelSense methods. The main components of a BabelSense are:
1. BabelSynset (the synset the sense belongs to)
2. BabelPOS (its part-of-speech tag)
3. the lemma string (the lexicalization of the sense)
4. BabelSensePhonetics (the written and audio pronunciations of this sense)
5. BabelSenseSource (the source of the sense, e.g.: Wikipedia, WordNet, etc., see above)

Some code retrieving the above information follows:
  1. BabelSense bs = by.getMainSense(Language.EN);  
  2.   
  3. // Gets the language of this BabelSense  
  4. Language lang = bs.getLanguage();  
  5.   
  6. // Gets the part-of-speech tag of this BabelSense  
  7. BabelPOS pos = bs.getPOS();  
  8.   
  9. // True if the BabelSense is a key concept  
  10. boolean iskeyConcept = bs.isKeyConcept();  
  11.   
  12. // Gets the lemma of this BabelSense  
  13. String lemma = bs.getLemma();  
  14.   
  15. // Gets the simple lemma of this sense (i.e., without parentheses, etc.)  
  16. String simpleLemma = bs.getSimpleLemma();  
  17.   
  18. // Gets the pronunciations of this sense  
  19. BabelSensePhonetics pronunciations = bs.getPronunciations();  
  20.   
  21. // Collects all the sources of the sense; ex: Wikipedia, WordNet, etc.  
  22. BabelSenseSource source = bs.getSource();  
Usage examples
Here we show full examples that show how you can use the BabelNet API to accomplish several tasks.

Retrieve all BabelSynset objects for a specific word
  1. import it.uniroma1.lcl.babelnet.BabelNet;  
  2. import it.uniroma1.lcl.babelnet.BabelSynset;  
  3. import it.uniroma1.lcl.jlt.util.Language;  
  4. import java.io.IOException;  
  5.   
  6. public class Example {  
  7.     public static void main(String[] args) throws IOException {  
  8.         BabelNet bn = BabelNet.getInstance();  
  9.         for (BabelSynset synset : bn.getSynsets("home", Language.EN)) {  
  10.             System.out.println("Synset ID: " + synset.getId());  
  11.         }  
  12.     }  
  13. }  

For a specific word retrieves all BabelSynset objects in English, Italian and French.
  1. import it.uniroma1.lcl.babelnet.BabelNet;  
  2. import it.uniroma1.lcl.babelnet.BabelSynset;  
  3. import it.uniroma1.lcl.jlt.util.Language;  
  4. import java.io.IOException;  
  5. import java.util.Arrays;  
  6.   
  7. public class Example {  
  8.     public static void main(String[] args) throws IOException {  
  9.         BabelNet bn = BabelNet.getInstance();  
  10.         for (BabelSynset synset : bn.getSynsets("home", Language.EN, Arrays.asList(Language.IT, Language.FR))) {  
  11.             System.out.println("Synset ID: " + synset.getId());  
  12.         }  
  13.     }  
  14. }  

Retrieve all BabelSense objects for a specific BabelSynset object
  1. import it.uniroma1.lcl.babelnet.BabelNet;  
  2. import it.uniroma1.lcl.babelnet.BabelSynsetID;  
  3. import it.uniroma1.lcl.babelnet.InvalidBabelSynsetIDException;  
  4. import it.uniroma1.lcl.babelnet.data.BabelAudio;  
  5. import it.uniroma1.lcl.babelnet.data.BabelSense;  
  6. import it.uniroma1.lcl.babelnet.data.BabelSensePhonetics;  
  7. import java.io.IOException;  
  8.   
  9. public class Example {  
  10.     public static void main(String[] args) throws IOException, InvalidBabelSynsetIDException {  
  11.         BabelNet bn = BabelNet.getInstance();  
  12.         for (BabelSense sense : bn.getSynset(new BabelSynsetID("bn:00000356n"))) {  
  13.             System.out.println("Sense: " + sense.getLemma()  
  14.                             + "\tLanguage: " + sense.getLanguage().toString()  
  15.                             + "\tSource: " + sense.getSource().toString());  
  16.             BabelSensePhonetics phonetic = sense.getPronunciations();  
  17.             for (BabelAudio audio : phonetic.getAudioItems()) {  
  18.                 System.out.println("Audio URL " + audio.getValidatedUrl());  
  19.             }  
  20.         }  
  21.     }  
  22. }  

Retrieve all BabelSense objects for a specific Wikidata page id
  1. import java.io.IOException;  
  2. import it.uniroma1.lcl.babelnet.BabelNet;  
  3. import it.uniroma1.lcl.babelnet.data.BabelSense;  
  4. import it.uniroma1.lcl.babelnet.data.BabelAudio;  
  5. import it.uniroma1.lcl.babelnet.data.BabelSensePhonetics;  
  6. import it.uniroma1.lcl.babelnet.resources.WikidataID;  
  7.   
  8.   
  9. public class Example {  
  10.     public static void main(String[] args) throws IOException {  
  11.         BabelNet bn = BabelNet.getInstance();  
  12.         for (BabelSense sense : bn.getSynset(new WikidataID("Q4837690"))) {  
  13.             System.out.println("Sense: " + sense.getLemma()  
  14.                             + "\tLanguage: " + sense.getLanguage().toString()  
  15.                             + "\tSource: " + sense.getSource().toString());  
  16.             BabelSensePhonetics phonetic = sense.getPronunciations();  
  17.             for (BabelAudio audio : phonetic.getAudioItems()) {  
  18.                 System.out.println("Audio URL " + audio.getValidatedUrl());  
  19.             }  
  20.         }  
  21.     }  
  22. }  

Retrieve Wikidata id for each BabelSense in a BabelSynset
  1. import it.uniroma1.lcl.babelnet.BabelNet;  
  2. import it.uniroma1.lcl.babelnet.BabelNet;  
  3. import it.uniroma1.lcl.babelnet.BabelSense;  
  4. import it.uniroma1.lcl.babelnet.BabelSynset;  
  5. import it.uniroma1.lcl.babelnet.BabelSynsetID;  
  6. import it.uniroma1.lcl.babelnet.InvalidBabelSynsetIDException;  
  7. import it.uniroma1.lcl.babelnet.data.BabelSenseSource;  
  8. import java.io.IOException;  
  9.   
  10. public class Example {  
  11.     public static void main(String[] args) throws IOException, InvalidBabelSynsetIDException {  
  12.        BabelNet bn = BabelNet.getInstance();  
  13.        BabelSynset by = bn.getSynset(new BabelSynsetID("bn:00000288n"));  
  14.        for (BabelSense sense : by.getSenses(BabelSenseSource.WIKIDATA)) {  
  15.            String sensekey = sense.getSensekey();  
  16.            System.out.println(sense.getLemma() + "\t" + sense.getLanguage() + "\t" + sensekey);  
  17.        }  
  18.    }  
  19. }  

Retrieve neighbors of a BabelSynset object
  1. import it.uniroma1.lcl.babelnet.BabelNet;  
  2. import it.uniroma1.lcl.babelnet.BabelSynset;  
  3. import it.uniroma1.lcl.babelnet.BabelSynsetID;  
  4. import it.uniroma1.lcl.babelnet.BabelSynsetIDRelation;  
  5. import it.uniroma1.lcl.babelnet.InvalidBabelSynsetIDException;  
  6. import it.uniroma1.lcl.jlt.util.Language;  
  7.   
  8. import java.io.IOException;  
  9.   
  10. public class Example {  
  11.     public static void main(String[] args) throws IOException, InvalidBabelSynsetIDException {  
  12.         BabelNet bn = BabelNet.getInstance();  
  13.         BabelSynset by = bn.getSynset(new BabelSynsetID("bn:00044492n"));  
  14.         for(BabelSynsetIDRelation edge : by.getEdges()) {  
  15.             System.out.println(by.getId()+"\t"+by.getMainSense(Language.EN).getLemma()+" - "  
  16.                 + edge.getPointer()+" - "  
  17.                 + edge.getBabelSynsetIDTarget());  
  18.         }  
  19.     }  
  20. }  

Retrieve all hypernyms (上位詞) of a BabelSynset object
  1. import it.uniroma1.lcl.babelnet.BabelNet;  
  2. import it.uniroma1.lcl.babelnet.BabelSynset;  
  3. import it.uniroma1.lcl.babelnet.BabelSynsetID;  
  4. import it.uniroma1.lcl.babelnet.BabelSynsetIDRelation;  
  5. import it.uniroma1.lcl.babelnet.InvalidBabelSynsetIDException;  
  6. import it.uniroma1.lcl.jlt.util.Language;  
  7.   
  8. import java.io.IOException;  
  9.   
  10. public class Example {  
  11.     public static void main(String[] args) throws IOException, InvalidBabelSynsetIDException {  
  12.         BabelNet bn = BabelNet.getInstance();  
  13.         BabelSynset by = bn.getSynset(new BabelSynsetID("bn:00015556n"));  
  14.         for(BabelSynsetIDRelation edge : by.getEdges(BabelPointer.ANY_HYPERNYM)) {  
  15.             System.out.println(by.getId()+"\t"+by.getMainSense(Language.EN).getLemma()+" - "  
  16.                 + edge.getPointer()+" - "  
  17.                 + edge.getBabelSynsetIDTarget());  
  18.         }  
  19.     }  
  20. }  

Retrieve all surface forms of a BabelSynset object
  1. import java.io.IOException;  
  2. import java.util.Map;  
  3. import java.util.Spliterator;  
  4. import java.util.Spliterators;  
  5. import java.util.function.Function;  
  6. import java.util.stream.Collectors;  
  7. import java.util.stream.Stream;  
  8. import java.util.stream.StreamSupport;  
  9.   
  10. import it.uniroma1.lcl.babelnet.BabelNet;  
  11. import it.uniroma1.lcl.babelnet.BabelSynset;  
  12.   
  13. public class Example {  
  14.     public static void main(String[] args) throws IOException, InvalidBabelSynsetIDException {  
  15.         BabelNet bn = BabelNet.getInstance();  
  16.         for(String form : by.getOtherForms(Language.EN)) {  
  17.             System.out.println(by.getId()+"\t"+by.getMainSense(Language.EN).getLemma()+" - "  
  18.                 + form);  
  19.         }  
  20.     }  
  21. }  

Retrieve the distribution of relationships (frequency of each BabelPointer type) for a specific word
  1. import java.io.IOException;  
  2. import java.util.List;  
  3. import java.util.Map;  
  4. import java.util.function.Function;  
  5. import java.util.stream.Collectors;  
  6.   
  7. import it.uniroma1.lcl.babelnet.BabelNet;  
  8. import it.uniroma1.lcl.babelnet.BabelSynset;  
  9. import it.uniroma1.lcl.babelnet.InvalidBabelSynsetIDException;  
  10. import it.uniroma1.lcl.jlt.util.Language;  
  11.   
  12. public class Example {  
  13.     public static void main(String[] args) throws IOException, InvalidBabelSynsetIDException {  
  14.   
  15.         BabelNet bn = BabelNet.getInstance();  
  16.         List synsets = bn.getSynsets("car", Language.EN);  
  17.           
  18.         Map totalByDept = synsets.parallelStream()  
  19.             .flatMap( synset ->  synset.getEdges().parallelStream())  
  20.             .map( edge -> edge.getPointer().getSymbol())  
  21.             .collect(Collectors.groupingByConcurrent(Function.identity(), Collectors.counting()));  
  22.           
  23.         totalByDept.forEach((pointer, freq) -> System.out.println(pointer + "\t" + freq));  
  24.     }  
  25. }  


沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!