pascal.taie.util.collection.AbstractMultiMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tai-e Show documentation
Show all versions of tai-e Show documentation
An easy-to-learn/use static analysis framework for Java
The newest version!
/*
* Tai-e: A Static Analysis Framework for Java
*
* Copyright (C) 2022 Tian Tan
* Copyright (C) 2022 Yue Li
*
* This file is part of Tai-e.
*
* Tai-e is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Tai-e is distributed in the hope that it will be useful,but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Tai-e. If not, see .
*/
package pascal.taie.util.collection;
import javax.annotation.Nonnull;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
public abstract class AbstractMultiMap implements MultiMap {
protected static final String NULL_KEY = "MultiMap does not permit null keys";
protected static final String NULL_VALUE = "MultiMap does not permit null values";
@Override
public boolean containsValue(V value) {
for (K key : keySet()) {
if (get(key).contains(value)) {
return true;
}
}
return false;
}
/**
* The cache of {@link AbstractMultiMap#entrySet()}.
*/
private transient Set> entrySet;
@Override
public Set> entrySet() {
var es = entrySet;
if (es == null) {
es = Collections.unmodifiableSet(new EntrySet());
entrySet = es;
}
return es;
}
private final class EntrySet extends AbstractSet> {
@Override
public boolean contains(Object o) {
if (o instanceof Map.Entry, ?> entry) {
//noinspection unchecked
return AbstractMultiMap.this.contains(
(K) entry.getKey(), (V) entry.getValue());
}
return false;
}
@Override
@Nonnull
public Iterator> iterator() {
return entryIterator();
}
@Override
public int size() {
return AbstractMultiMap.this.size();
}
}
protected abstract Iterator> entryIterator();
/**
* The cache of {@link AbstractMultiMap#values()}.
*/
private transient Collection values;
@Override
public Collection values() {
Collection vals = values;
if (vals == null) {
vals = Views.toMappedCollection(entrySet(), Map.Entry::getValue,
o -> containsValue((V) o));
values = vals;
}
return vals;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof MultiMap)) {
return false;
}
@SuppressWarnings("unchecked")
MultiMap that = (MultiMap) o;
if (size() != that.size()) {
return false;
}
try {
for (K key : keySet()) {
if (!get(key).equals(that.get(key))) {
return false;
}
}
} catch (ClassCastException | NullPointerException ignored) {
return false;
}
return true;
}
@Override
public String toString() {
StringJoiner joiner = new StringJoiner(", ", "{", "}");
for (K key : keySet()) {
joiner.add(key + "=" + get(key));
}
return joiner.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy