001/* 002 * Copyright 2018 Paul Schaub. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.pgpainless.util; 017 018import javax.annotation.Nonnull; 019import java.util.Collection; 020import java.util.HashMap; 021import java.util.HashSet; 022import java.util.Map; 023import java.util.Set; 024 025public class MultiMap<K, V> { 026 027 private final Map<K, Set<V>> map; 028 029 public MultiMap() { 030 map = new HashMap<>(); 031 } 032 033 public MultiMap(@Nonnull MultiMap<K, V> other) { 034 this.map = new HashMap<>(); 035 for (K k : other.map.keySet()) { 036 map.put(k, new HashSet<>(other.map.get(k))); 037 } 038 } 039 040 public MultiMap(@Nonnull Map<K, Set<V>> content) { 041 this.map = new HashMap<>(content); 042 } 043 044 public int size() { 045 return map.size(); 046 } 047 048 public boolean isEmpty() { 049 return map.isEmpty(); 050 } 051 052 public boolean containsKey(K o) { 053 return map.containsKey(o); 054 } 055 056 public boolean containsValue(V o) { 057 for (Set<V> values : map.values()) { 058 if (values.contains(o)) return true; 059 } 060 return false; 061 } 062 063 public Set<V> get(K o) { 064 return map.get(o); 065 } 066 067 public void put(K k, V v) { 068 Set<V> values = map.get(k); 069 if (values == null) { 070 values = new HashSet<>(); 071 map.put(k, values); 072 } 073 values.add(v); 074 } 075 076 public void put(K k, Set<V> vs) { 077 for (V v : vs) { 078 put(k, v); 079 } 080 } 081 082 public void remove(K o) { 083 for (Set<V> values : map.values()) { 084 values.remove(o); 085 } 086 } 087 088 public void putAll(Map<? extends K, ? extends Set<V>> _map) { 089 for (K key : _map.keySet()) { 090 Set<V> vs = this.map.get(key); 091 if (vs == null) { 092 vs = new HashSet<>(); 093 this.map.put(key, vs); 094 } 095 vs.addAll(_map.get(key)); 096 } 097 } 098 099 public void clear() { 100 map.clear(); 101 } 102 103 public Set<K> keySet() { 104 return map.keySet(); 105 } 106 107 public Collection<Set<V>> values() { 108 return map.values(); 109 } 110 111 public Set<Map.Entry<K, Set<V>>> entrySet() { 112 return map.entrySet(); 113 } 114 115 @Override 116 public boolean equals(Object o) { 117 if (o == null) { 118 return false; 119 } 120 121 if (!(o instanceof MultiMap)) { 122 return false; 123 } 124 125 if (this == o) { 126 return true; 127 } 128 129 return map.equals(((MultiMap) o).map); 130 } 131 132 @Override 133 public int hashCode() { 134 return map.hashCode(); 135 } 136}