All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.jersey.internal.guava.Maps Maven / Gradle / Ivy

Go to download

A bundle project producing JAX-RS RI bundles. The primary artifact is an "all-in-one" OSGi-fied JAX-RS RI bundle (jaxrs-ri.jar). Attached to that are two compressed JAX-RS RI archives. The first archive (jaxrs-ri.zip) consists of binary RI bits and contains the API jar (under "api" directory), RI libraries (under "lib" directory) as well as all external RI dependencies (under "ext" directory). The secondary archive (jaxrs-ri-src.zip) contains buildable JAX-RS RI source bundle and contains the API jar (under "api" directory), RI sources (under "src" directory) as well as all external RI dependencies (under "ext" directory). The second archive also contains "build.xml" ANT script that builds the RI sources. To build the JAX-RS RI simply unzip the archive, cd to the created jaxrs-ri directory and invoke "ant" from the command line.

There is a newer version: 3.1.9
Show newest version
/*
 * Copyright (C) 2007 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.glassfish.jersey.internal.guava;

import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.function.Function;
import java.util.function.Predicate;

import org.glassfish.jersey.internal.guava.Joiner.MapJoiner;

import static org.glassfish.jersey.internal.guava.Preconditions.checkArgument;
import static org.glassfish.jersey.internal.guava.Preconditions.checkNotNull;
import static org.glassfish.jersey.internal.guava.Predicates.compose;

/**
 * Static utility methods pertaining to {@link Map} instances (including instances of
 * {@link SortedMap}, {@link BiMap}, etc.). Also see this class's counterparts
 * {@link Lists}, {@link Sets} and {@link Queues}.
 * 

*

See the Guava User Guide article on * {@code Maps}. * * @author Kevin Bourrillion * @author Mike Bostock * @author Isaac Shum * @author Louis Wasserman * @since 2.0 (imported from Google Collections Library) */ public final class Maps { private static final MapJoiner STANDARD_JOINER = Collections2.STANDARD_JOINER.withKeyValueSeparator(); private Maps() { } @SuppressWarnings("unchecked") private static Function, K> keyFunction() { return (Function) EntryFunction.KEY; } @SuppressWarnings("unchecked") private static Function, V> valueFunction() { return (Function) EntryFunction.VALUE; } private static Iterator keyIterator(Iterator> entryIterator) { return Iterators.transform(entryIterator, Maps.keyFunction()); } static Iterator valueIterator(Iterator> entryIterator) { return Iterators.transform(entryIterator, Maps.valueFunction()); } /** * Creates a {@code HashMap} instance, with a high enough "initial capacity" * that it should hold {@code expectedSize} elements without growth. * This behavior cannot be broadly guaranteed, but it is observed to be true * for OpenJDK 1.6. It also can't be guaranteed that the method isn't * inadvertently oversizing the returned map. * * @param expectedSize the number of elements you expect to add to the * returned map * @return a new, empty {@code HashMap} with enough capacity to hold {@code * expectedSize} elements without resizing * @throws IllegalArgumentException if {@code expectedSize} is negative */ public static HashMap newHashMapWithExpectedSize( int expectedSize) { return new HashMap(capacity(expectedSize)); } /** * Returns a capacity that is sufficient to keep the map from being resized as * long as it grows no larger than expectedSize and the load factor is >= its * default (0.75). */ static int capacity(int expectedSize) { if (expectedSize < 3) { CollectPreconditions.checkNonnegative(expectedSize, "expectedSize"); return expectedSize + 1; } if (expectedSize < Ints.MAX_POWER_OF_TWO) { return expectedSize + expectedSize / 3; } return Integer.MAX_VALUE; // any large value } static Iterator> asMapEntryIterator( Set set, final Function function) { return new TransformedIterator>(set.iterator()) { @Override Entry transform(final K key) { return immutableEntry(key, function.apply(key)); } }; } private static Set removeOnlySet(final Set set) { return new ForwardingSet() { @Override protected Set delegate() { return set; } @Override public boolean add(E element) { throw new UnsupportedOperationException(); } @Override public boolean addAll(Collection es) { throw new UnsupportedOperationException(); } }; } private static SortedSet removeOnlySortedSet(final SortedSet set) { return new ForwardingSortedSet() { @Override protected SortedSet delegate() { return set; } @Override public boolean add(E element) { throw new UnsupportedOperationException(); } @Override public boolean addAll(Collection es) { throw new UnsupportedOperationException(); } @Override public SortedSet headSet(E toElement) { return removeOnlySortedSet(super.headSet(toElement)); } @Override public SortedSet subSet(E fromElement, E toElement) { return removeOnlySortedSet(super.subSet(fromElement, toElement)); } @Override public SortedSet tailSet(E fromElement) { return removeOnlySortedSet(super.tailSet(fromElement)); } }; } /** * Returns an immutable map entry with the specified key and value. The {@link * Entry#setValue} operation throws an {@link UnsupportedOperationException}. *

*

The returned entry is serializable. * * @param key the key to be associated with the returned entry * @param value the value to be associated with the returned entry */ public static Entry immutableEntry( K key, V value) { return new ImmutableEntry(key, value); } static Predicate> keyPredicateOnEntries(Predicate keyPredicate) { return compose(keyPredicate, Maps.keyFunction()); } static Predicate> valuePredicateOnEntries(Predicate valuePredicate) { return compose(valuePredicate, Maps.valueFunction()); } /** * Delegates to {@link Map#get}. Returns {@code null} on {@code * ClassCastException} and {@code NullPointerException}. */ static V safeGet(Map map, Object key) { checkNotNull(map); try { return map.get(key); } catch (ClassCastException e) { return null; } catch (NullPointerException e) { return null; } } /** * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code * ClassCastException} and {@code NullPointerException}. */ static boolean safeContainsKey(Map map, Object key) { checkNotNull(map); try { return map.containsKey(key); } catch (ClassCastException e) { return false; } catch (NullPointerException e) { return false; } } /** * Delegates to {@link Map#remove}. Returns {@code null} on {@code * ClassCastException} and {@code NullPointerException}. */ static V safeRemove(Map map, Object key) { checkNotNull(map); try { return map.remove(key); } catch (ClassCastException e) { return null; } catch (NullPointerException e) { return null; } } private enum EntryFunction implements Function, Object> { KEY { @Override public Object apply(Entry entry) { return entry.getKey(); } }, VALUE { @Override public Object apply(Entry entry) { return entry.getValue(); } } } private static class AsMapView extends ImprovedAbstractMap { final Function function; private final Set set; AsMapView(Set set, Function function) { this.set = checkNotNull(set); this.function = checkNotNull(function); } Set backingSet() { return set; } @Override public Set createKeySet() { return removeOnlySet(backingSet()); } @Override Collection createValues() { return Collections2.transform(set, function); } @Override public int size() { return backingSet().size(); } @Override public boolean containsKey(Object key) { return backingSet().contains(key); } @Override public V get(Object key) { if (Collections2.safeContains(backingSet(), key)) { @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it K k = (K) key; return function.apply(k); } else { return null; } } @Override public V remove(Object key) { if (backingSet().remove(key)) { @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it K k = (K) key; return function.apply(k); } else { return null; } } @Override public void clear() { backingSet().clear(); } @Override protected Set> createEntrySet() { return new EntrySet() { @Override Map map() { return Maps.AsMapView.this; } @Override public Iterator> iterator() { return asMapEntryIterator(backingSet(), function); } }; } } /** * {@code AbstractMap} extension that implements {@link #isEmpty()} as {@code * entrySet().isEmpty()} instead of {@code size() == 0} to speed up * implementations where {@code size()} is O(n), and it delegates the {@code * isEmpty()} methods of its key set and value collection to this * implementation. */ abstract static class ImprovedAbstractMap extends AbstractMap { private transient Set> entrySet; private transient Set keySet; private transient Collection values; /** * Creates the entry set to be returned by {@link #entrySet()}. This method * is invoked at most once on a given map, at the time when {@code entrySet} * is first called. */ abstract Set> createEntrySet(); @Override public Set> entrySet() { Set> result = entrySet; return (result == null) ? entrySet = createEntrySet() : result; } @Override public Set keySet() { Set result = keySet; return (result == null) ? keySet = createKeySet() : result; } Set createKeySet() { return new KeySet(this); } @Override public Collection values() { Collection result = values; return (result == null) ? values = createValues() : result; } Collection createValues() { return new Values(this); } } static class KeySet extends Sets.ImprovedAbstractSet { final Map map; KeySet(Map map) { this.map = checkNotNull(map); } Map map() { return map; } @Override public Iterator iterator() { return keyIterator(map().entrySet().iterator()); } @Override public int size() { return map().size(); } @Override public boolean isEmpty() { return map().isEmpty(); } @Override public boolean contains(Object o) { return map().containsKey(o); } @Override public boolean remove(Object o) { if (contains(o)) { map().remove(o); return true; } return false; } @Override public void clear() { map().clear(); } } static class Values extends AbstractCollection { final Map map; Values(Map map) { this.map = checkNotNull(map); } final Map map() { return map; } @Override public Iterator iterator() { return valueIterator(map().entrySet().iterator()); } @Override public boolean remove(Object o) { try { return super.remove(o); } catch (UnsupportedOperationException e) { for (Entry entry : map().entrySet()) { if (Objects.equals(o, entry.getValue())) { map().remove(entry.getKey()); return true; } } return false; } } @Override public boolean removeAll(Collection c) { try { return super.removeAll(checkNotNull(c)); } catch (UnsupportedOperationException e) { Set toRemove = Sets.newHashSet(); for (Entry entry : map().entrySet()) { if (c.contains(entry.getValue())) { toRemove.add(entry.getKey()); } } return map().keySet().removeAll(toRemove); } } @Override public boolean retainAll(Collection c) { try { return super.retainAll(checkNotNull(c)); } catch (UnsupportedOperationException e) { Set toRetain = Sets.newHashSet(); for (Entry entry : map().entrySet()) { if (c.contains(entry.getValue())) { toRetain.add(entry.getKey()); } } return map().keySet().retainAll(toRetain); } } @Override public int size() { return map().size(); } @Override public boolean isEmpty() { return map().isEmpty(); } @Override public boolean contains(Object o) { return map().containsValue(o); } @Override public void clear() { map().clear(); } } abstract static class EntrySet extends Sets.ImprovedAbstractSet> { abstract Map map(); @Override public int size() { return map().size(); } @Override public void clear() { map().clear(); } @Override public boolean contains(Object o) { if (o instanceof Entry) { Entry entry = (Entry) o; Object key = entry.getKey(); V value = Maps.safeGet(map(), key); return Objects.equals(value, entry.getValue()) && (value != null || map().containsKey(key)); } return false; } @Override public boolean isEmpty() { return map().isEmpty(); } @Override public boolean remove(Object o) { if (contains(o)) { Entry entry = (Entry) o; return map().keySet().remove(entry.getKey()); } return false; } @Override public boolean removeAll(Collection c) { try { return super.removeAll(checkNotNull(c)); } catch (UnsupportedOperationException e) { // if the iterators don't support remove return Sets.removeAllImpl(this, c.iterator()); } } @Override public boolean retainAll(Collection c) { try { return super.retainAll(checkNotNull(c)); } catch (UnsupportedOperationException e) { // if the iterators don't support remove Set keys = Sets.newHashSetWithExpectedSize(c.size()); for (Object o : c) { if (contains(o)) { Entry entry = (Entry) o; keys.add(entry.getKey()); } } return map().keySet().retainAll(keys); } } } }