004-guava set - a set of new type -MultiSet, MultiMap, BiMap, Table, ClassToInstanceMap, RangeSe, RangeMap etc.

I. Overview

  Guava introduced many JDK does not have, but obviously useful new collection types. These new types of frame are set to coexist and JDK, but not in the abstract concept to be forced upon the other set JDK. As a general rule, Guava collection of very precisely follows the JDK interface contract.

Second, the use

2.1, MultiSet [disordered + reusable ] - Tools Multisets

  Guava offers a new collection type  Multiset , it can add multiple equal elements. Wikipedia Multiset Mathematically this definition: "set [SET] extending the concept, its elements can be set with recurring ... [SET] with the same tuple [tuple] In contrast, the order is irrelevant elements Multiset : Multiset {a, a, b } and {a, b, a} are equal. " - Translator's Note: Here's a collection of said [set] is a mathematical concept, Multiset inherited from the Collection interface in JDK, not the Set interface, it contains no duplicate elements did not violate the original interface contract.

  This interface does not implement the interface java.util.Set, Set Interface provisions which are not able to put in repeated elements, if put into repeating elements will be overwritten; however Multiset the interface is repeating elements can be placed, Set interface elements are [1,2,3], Multiset indeed be in [1✖️2,2✖️3,3✖️3] to represent a plurality of like elements.

Providing Multiset achieve a variety of Guava of, substantially corresponds to various implementations of Map JDK:

Map Corresponding Multiset Whether to support null elements
HashMap HashMultiset Yes
TreeMap TreeMultiset It is (if comparator supports it)
LinkedHashMap LinkedHashMultiset Yes
ConcurrentHashMap ConcurrentHashMultiset no
ImmutableMap ImmutableMultiset no

use

    @Test
    public void testMultiSet(){
        Multiset<String> multiset= HashMultiset.create();
        multiset.add("aa");
        multiset.add("bb");
        multiset.add("cc",2);
        System.out.println(multiset);//[aa, bb, cc x 2]
        System.out.println(multiset.size()); //4
        System.out.println(multiset.count("cc"));//2
        multiset.setCount("bb",4);
        System.out.println(multiset);//[aa, bb x 4, cc x 2]
    }

  

2.2、SortedMultiset

  SortedMultiset Multiset interface is a variant, which supports efficient access to a subset of the specified range. For example, you can use latencies.subMultiset (0, BoundType.CLOSED, 100, BoundType.OPEN) .size () to count the delay visit your site within 100 milliseconds, then this value and latencies.size () compared to obtain this level of delay in the overall proportion of access.

  TreeMultiset achieve SortedMultiset interface. In the time of this writing, ImmutableSortedMultiset also compatibility testing and GWT.

2.3, the MultiMap [Key -value may be repeated Key ] - Tools Multimaps

  Program development using Map <K, List <V >> or Map <K, Set <V >> , and to endure the awkward structure. For example, Map <K, Set <V >> generally used to refer to the non-calibration has FIG. The Guava  Multimap can easily be mapped to a plurality of key values. In other words, Multimap a general manner the key mapped to any number of values.

  Multimap rarely used directly interface more often you will use ListMultimap or SetMultimap interfaces, which are the keys to the List or Set.

  Multimap provides various forms of implementation. In most want to use Map <K, Collection <V >> place, you can use them:

achieve Similar behavior bond Value-like behavior
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap* LinkedHashMap* LinkedList*
LinkedHashMultimap** LinkedHashMap LinkedHashMap
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
ImmutableSetMultimap ImmutableMap ImmutableSet

  In addition to two immutable form of realization, all other implementations support null keys and null values

  * LinkedListMultimap.entries () preserves the iteration order all the keys and values. For details, see doc links.

  ** LinkedHashMultimap retains the insertion order mapping entry, including the order of insertion of the key, and an insertion order of all the values ​​of the key map.

  Please note that not all of Multimap and are listed above, use the Map <K, Collection <V >> is achieved (in particular, some of Multimap implemented a custom hashTable, to minimize overhead)

  If you want more customization, please use Multimaps.newMultimap (Map, Supplier <Collection> ) or list and  set versions, using a custom Collection, List or Set realize Multimap.

Example:

    @Test
     public  void testMultiMap () { 
        Multimap <String, String> = the multimap ArrayListMultimap.create (); 
        multimap.put ( "Fruit", "bannana" ); 
        multimap.put ( "Fruit", "Apple"); // key may be repeated 
        multimap.put ( "Fruit", "Apple"); // value may be repeated, will not overwrite the previous 
        multimap.put ( "Fruit", "Peach" ); 
        multimap.put ( "FISH", "crucian "); // European carp 
        multimap.put (" FISH "," cARP "); // carp 
        Collection <String> fruits = multimap.get("fruit");String> fruits = multimap.get("fruit"
        System.err.println(fruits);//[bannana, apple, apple, peach]
        
        //对比 HashMultimap
        Multimap<String,String> multimap2= HashMultimap.create();
        multimap2.put("fruit2", "bannana");
        multimap2.put("fruit2", "apple");
        multimap2.put("fruit2", "apple");

        System.err.println(multimap2.size());//2
        System.err.println(multimap2.get("fruit2"));//[apple, bannana]     注意: 这里只有一个apple
    }

2.4, BiMap [Bidirectional the Map (Bidirectional the Map) values can not be repeated bond ]

  Traditionally, bi-directional mapping of key-value pairs need to maintain two separate map, and maintain synchronization between them. However, this approach is error-prone, but also for the values ​​that have been the case in the map, it will become very confusing. E.g:

The Map <String, Integer> nameToId = Maps.newHashMap (); 
map <Integer, String> idToName = Maps.newHashMap (); 
nameToId.put ( "Bob", 42 is ); 
idToName.put ( 42 is, "Bob" );
 // If "Bob" and 42 already, what happens in the map?
 // If we forget to synchronize the two map, there will be strange bug occurs ...

BiMap <K, V> is a special Map:

  May be inverse () inverted BiMap <K, V> value mapping
  to ensure the values are unique, so values () Returns Collection Set instead of the ordinary
  in BiMap, if you want the key mapped to a value already exists, IllegalArgumentException will be thrown. If a particular value, you want to force it to replace the key, use the BiMap.forcePut (key, value).

    @Test
    public void testBiMap() {
        BiMap<String, Integer> userId = HashBiMap.create();
        userId.put("lhx",30);
        userId.put("zll",28);
        String userForId = userId.inverse().get(30);
        System.out.println(userForId);//lhx

        userId.put("jm",30);//报错
        String userForId2 = userId.inverse().get(30);
        System.out.println(userForId2);//lhx
    }

The realization of various BiMap

Key - value realization Value - key to achieve Corresponding BiMap achieve
HashMap HashMap HashBiMap
ImmutableMap ImmutableMap ImmutableBiMap
EnumMap EnumMap EnumBiMap
EnumMap HashMap EnumHashBiMap

Note: Maps category there are some methods such as synchronizedBiMap of BiMap tools.

2.5, Table [a double bond the Map the Map -> the Table -> rowKey + columnKey + value primary key and // a bit like the sql ] - Tools Tables

  Row, column, value. When using multiple keys indexed, you may use a similar Map FirstName, Map LastName, Person >> implementation <<, very ugly this way, the use is not friendly.

  Guava aims to provide a new type of collection the Table , it has two supports all types of keys: "row" and "column."

  Table There are several implementation:

  • HashBasedTable : <R & lt, HashMap <C, V >> HashMap essentially implemented;
  • TreeBasedTable : essentially implemented by TreeMap <R, TreeMap <C, V >>;
  • ImmutableTable ImmutableTable dense or sparse data set has optimized:;: Note <R, ImmutableMap <C, V >> ImmutableMap essentially implemented.
  • ArrayTable : required when constructing the designation of rows and columns, in essence, is implemented by a two-dimensional array, to improve access speed and intensity Table memory utilization. ArrayTable and other Table works a little differently, see Javadoc for details.

Examples

    @Test
    public void testTable() {
        Table<String, String, Integer> table = HashBasedTable.create();
        table.put("a", "b", 4);
        table.put("a", "c", 20);
        table.put("b", "c", 5);

        Map<String, Integer> a = table.row("a");// returns a Map mapping {b=4, c=20}
        System.out.println(a);

        Map<String, Integer> column = table.column("c");// returns a Map mapping {a=20, b=5}
        System.out.println(column);

        Integer integer = table.get("a", "c");
        System.out.println(integer); //20
    }

2.6、ClassToInstanceMap

  ClassToInstanceMap is a special Map: it is the type of key, and the key values ​​are in line with the object of the type referred to.

  To extend the Map interface, ClassToInstanceMap declares two additional methods: T the getInstance (Class <T>)  and T PutInstance (Class <T>, T) , in order to avoid the cast, while ensuring the security type.

  ClassToInstanceMap have a unique generic parameters, commonly referred to as B, on behalf Map supports an upper bound of all types. E.g:

    class Person{
        private String name;

        public Person(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }

    @Test
    public void testClassToInstanceMap() {
        ClassToInstanceMap<Person> instanceMap=MutableClassToInstanceMap.create();
        instanceMap.putInstance(Person.class, new Person("lhx"));
        instanceMap.putInstance(Person.class, new Person("lhx2"));
        Person person = instanceMap.get(Person.class); // Person{name='lhx2'} 存储了 后一个
        System.out.println(person);
    }

  Technically, ClassToInstanceMap <B> achieved Map <Class <extends B>, B?> - or in other words, is a subtype B mapped to the corresponding instance Map. This allows generic declaration ClassToInstanceMap contained a little confusing, but remember that the upper bound of B is always supported by Map type - B is usually Object.

  For ClassToInstanceMap, Guava provides two useful implementations: MutableClassToInstanceMap and  ImmutableClassToInstanceMap .

2.7、RangeSet

  It describes a group of non-empty sections are not connected. When a section is added to the variable RangeSet, all sections will be connected to the merger, the empty zone are ignored. E.g:

    @Test
     public  void testRangeSet () { 
        RangeSet <Integer> = rangeSet TreeRangeSet.create (); 

        rangeSet.add (Range.closed ( . 1, 10)); // {[1,10]} 
        rangeSet.add (Range.closedOpen (11, 15)); // not linked interval: {[1,10], [11,15)} 
        rangeSet.add (Range.closedOpen (15, 20 is)); // connected interval; {[1,10 ], [11,20)} 
        rangeSet.add (Range.openClosed (0, 0)); // null interval; {[1,10], [11,20)} 
        rangeSet.remove (Range.open (. 5, 10)); // segmentation [. 1, 10]; {[l, 5], [10,10], [11,20)} 

        System.out.println (rangeSet); //[[1..5], [10..10], [11..20)]
    }

 

  Please note that, to merge Range.closed (1, 10), and an interval in Range.closedOpen (11, 15), you need to use Range.canonical (DiscreteDomain) of the pretreatment zone, e.g. DiscreteDomain.integers ().

  Note: RangeSet does not support GWT, does not support JDK5 and earlier; because, RangeSet takes full advantage of the characteristics of JDK6 in NavigableMap.

2.8 RangeMap

  RangeMap described "disjoint, non-empty interval" value to a specific mapping. And RangeSet different, RangeMap not merge adjacent map, even the adjacent sections map to the same value. E.g:

    @Test
    public void testRangeMap() {
        RangeMap<Integer, String> rangeMap = TreeRangeMap.create();

        rangeMap.put(Range.closed(1, 10), "foo"); //{[1,10] => "foo"}
        rangeMap.put(Range.open(3, 6), "bar"); //{[1,3] => "foo", (3,6) => "bar", [6,10] => "foo"}
        rangeMap.put(Range.open(10, 20), "foo"); //{[1,3] => "foo", (3,6) => "bar", [6,10] => "foo", (10,20) => "foo"}
        rangeMap.remove(Range.closed(5, 11)); //{[1,3] => "foo", (3,5) => "bar", (11,20) => "foo"}

        System.out.println(rangeMap);//[[1..3]=foo, (3..5)=bar, (11..20)=foo]
    }

 

 

 

 

 

 

 

 

 

 

the way

Guess you like

Origin www.cnblogs.com/bjlhx/p/11584060.html