Guava experience: new set type of guava -- Multiset

Guava introduces some new collection types that are not available in JDK, but are very useful. All these new set types can be smoothly integrated with the set in JDK. The guava set implements the JDK defined interface very precisely. The new sets defined in guava are:

  • Multiset
  • SortedMultiset
  • Multimap
  • ListMultimap
  • SetMultimap
  • BiMap
  • ClassToInstanceMap
  • Table

Multiset set

What is Multiset? As the name implies, the difference between Multiset and Set is that multiple identical objects can be saved. In JDK, a basic difference between a List and a Set is that a List can contain multiple identical objects in order, while a Set cannot have duplicates, and does not guarantee the order (some implementations have the order, such as LinkedHashSet and SortedSet, etc.) so Multiset occupies a gray area between a List and a Set: it is allowed to repeat, but does not guarantee the order.

Common usage scenarios: Multiset has a useful function to track the number of each object, so you can use it for statistics. Common common implementation methods are as follows:

@Test
    public void testWordCount(){
        String strWorld="wer|dffd|ddsa|dfd|dreg|de|dr|ce|ghrt|cf|gt|ser|tg|ghrt|cf|gt|" +
                "ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr|wer|dffd|ddsa|dfd|dreg|de|dr|" +
                "ce|ghrt|cf|gt|ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr";
        String[] words=strWorld.split("\\|");
        Map<String, Integer> countMap = new HashMap<String, Integer>();
        for (String word : words) {
            Integer count = countMap.get(word);
            if (count == null) { 
                countMap.put(word, 1); 
            }
            else { 
                countMap.put(word, count + 1); 
            }
        }        
        System.out.println("countMap: ");
        for(String key:countMap.keySet()){
            System.out.println(key+" count: "+countMap.get(key));
        }
    }

The function of the above code is very simple, which is used to record the number of times the string appears in the array. This kind of scenario is easy to appear in the actual development process. If you use a specific class to implement the Multiset interface, you can easily implement the above functional requirements:

public void testMultsetWordCount(){
    String strWorld="wer|dfd|dd|dfd|dda|de|dr";
    String[] words=strWorld.split("\\|");
    List<String> wordList=new ArrayList<String>();
    for (String word : words) {
        wordList.add(word);
    }
    Multiset<String> wordsMultiset = HashMultiset.create();
    wordsMultiset.addAll(wordList);
 
    for(String key:wordsMultiset.elementSet()){
        System.out.println(key+" count: "+wordsMultiset.count(key));
    }
}

Main methods of Multiset

The interfaces defined by Multiset interface mainly include:

  • add(E element): add a single element to it
  • Add (E element, int occurs): add a specified number of elements to it
  • count(Object element): returns the number of given parameter elements
  • remove(E element): remove an element and its count value will reduce the response
  • Remove (E element, int occurs): remove the corresponding number of elements
  • elementSet(): put different elements into a Set
  • entrySet(): similar to Map.entrySet Return to set< Multiset.Entry >. The included entry supports the use of getElement() and getCount()
  • Setcount (E element, int count): sets the number of repetitions of an element
  • setCount(E element,int oldCount,int newCount): changes an element that matches the original number of repetitions to a new number of repetitions
  • Retain all (collection C): keep all elements that appear in a given collection parameter
  • removeAll(Collectionc): removes all elements that appear to a given collection parameter

Examples of common methods:

@Test
    public void testMultsetWordCount(){
        String strWorld="wer|dfd|dd|dfd|dda|de|dr";
        String[] words=strWorld.split("\\|");
        List<String> wordList=new ArrayList<String>();
        for (String word : words) {
            wordList.add(word);
        }
        Multiset<String> wordsMultiset = HashMultiset.create();
        wordsMultiset.addAll(wordList);
        
        
        //System.out.println("wordsMultiset: "+wordsMultiset);
        
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count: "+wordsMultiset.count(key));
        }
        
        if(!wordsMultiset.contains("peida")){
            wordsMultiset.add("peida", 2);
        }
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count: "+wordsMultiset.count(key));
        }
        
        
        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 23);
        }
        
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count: "+wordsMultiset.count(key));
        }
        
        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 23,45);
        }
        
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count: "+wordsMultiset.count(key));
        }
        
        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 44,67);
        }
        
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count: "+wordsMultiset.count(key));
        }
    }

Output:

de count: 1
dda count: 1
dd count: 1
dfd count: 2
wer count: 1
dr count: 1
============================================
de count: 1
dda count: 1
dd count: 1
dfd count: 2
peida count: 2
wer count: 1
dr count: 1
============================================
de count: 1
dda count: 1
dd count: 1
dfd count: 2
peida count: 23
wer count: 1
dr count: 1
============================================
de count: 1
dda count: 1
dd count: 1
dfd count: 2
peida count: 45
wer count: 1
dr count: 1
============================================
de count: 1
dda count: 1
dd count: 1
dfd count: 2
peida count: 45
wer count: 1
dr count: 1

Description: setCount(E element,int oldCount,int newCount): method. If the incoming oldCount is inconsistent with the element's, the element's count cannot be set to newCount. Attention is needed.

Multiset is not a Map

It should be noted that multiset is not a map < e, integer >, although multiset provides some similar functions. Other notable differences are: the number of repeats of elements in multiset will only be positive, and the maximum number will not exceed Integer.MAX_VALUE. Elements with a count of 0 will not appear in multiset, nor in the return results of elementSet() and entrySet().

  • multiset.size() method returns the sum of all the elements, which is equivalent to adding all the repeated numbers. If you need to know the number of each element, you can use
  • elementSet().size() is obtained. (therefore, the call to add(E) method will be multiset.size() add 1)
  • multiset.iterator() will iterate over every element that appears, and the number of iterations is equal to multiset.size() same. iterates over each occurrence of each element, so the length of the iteration is equal to multiset.size().
  • Multiset supports adding, removing, and resetting the number of elements. Executing setCount(element,0) is equivalent to removing all the same elements from multiset.
  • call multiset.count(elem) method, if the element is not in the set, the result returned will only be 0.

Implementation of Multiset

Guava provides multiple implementations of Multiset, which basically correspond to the implementation of Map in JDK:

Map Corresponding Multiset Supports null elements
HashMap HashMultiset Yes
TreeMap TreeMultiset Yes (if the comparator does)
LinkedHashMap LinkedHashMultiset Yes
ConcurrentHashMap ConcurrentHashMultiset No
ImmutableMap ImmutableMultiset No

Tags: JDK

Posted on Sun, 07 Jun 2020 06:18:00 -0400 by soulroll