001/*-------------------------------------------------------------------------+ 002| | 003| Copyright 2005-2011 The ConQAT Project | 004| | 005| Licensed under the Apache License, Version 2.0 (the "License"); | 006| you may not use this file except in compliance with the License. | 007| You may obtain a copy of the License at | 008| | 009| http://www.apache.org/licenses/LICENSE-2.0 | 010| | 011| Unless required by applicable law or agreed to in writing, software | 012| distributed under the License is distributed on an "AS IS" BASIS, | 013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 014| See the License for the specific language governing permissions and | 015| limitations under the License. | 016+-------------------------------------------------------------------------*/ 017package org.conqat.lib.commons.collections; 018 019import java.util.Arrays; 020import java.util.HashSet; 021import java.util.Map; 022import java.util.Set; 023import java.util.function.Supplier; 024 025/** 026 * Manages a map of sets, i.e. each key can store multiple elements. 027 * 028 * @param <K> 029 * the key type. 030 * @param <V> 031 * the value type (i.e. the values stored in the collections). 032 */ 033public class SetMap<K, V> extends CollectionMap<K, V, Set<V>> { 034 035 private static final long serialVersionUID = 1L; 036 037 private final Supplier<Set<V>> setFactory; 038 039 public SetMap() { 040 this(HashSet::new); 041 } 042 043 public SetMap(Supplier<Set<V>> setFactory) { 044 this.setFactory = setFactory; 045 } 046 047 @SafeVarargs 048 public SetMap(SetMap<K, V>... otherMaps) { 049 this(determineFactory(otherMaps)); 050 for (SetMap<K, V> otherMap : otherMaps) { 051 addAll(otherMap); 052 } 053 } 054 055 private static <K, V> Supplier<Set<V>> determineFactory(SetMap<K, V>[] otherMaps) { 056 if (otherMaps.length > 0) { 057 return otherMaps[0].setFactory; 058 } 059 return HashSet::new; 060 } 061 062 @SafeVarargs 063 public SetMap(Map<K, Set<V>>... otherMaps) { 064 this(); 065 for (Map<K, Set<V>> otherMap : otherMaps) { 066 addAll(otherMap); 067 } 068 } 069 070 @Override 071 protected Set<V> createNewCollection() { 072 return setFactory.get(); 073 } 074 075 /** Inverts this SetMap, i.e. switches the keys and values. */ 076 public SetMap<V, K> invert() { 077 SetMap<V, K> invertedMap = new SetMap<>(); 078 for (K nowValue : this.getKeys()) { 079 for (V nowKey : this.getCollection(nowValue)) { 080 invertedMap.add(nowKey, nowValue); 081 } 082 } 083 return invertedMap; 084 } 085 086 /** Factory function for a {@link SetMap} with one entry. */ 087 public static <K, V> SetMap<K, V> of(K key, V... values) { 088 SetMap<K, V> result = new SetMap<>(); 089 result.addAll(key, Arrays.asList(values)); 090 return result; 091 } 092}