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

org.eclipse.collections.impl.multimap.AbstractMultimap Maven / Gradle / Ivy

There is a newer version: 12.0.0.M3
Show newest version
/*
 * Copyright (c) 2015 Goldman Sachs.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v. 1.0 which accompany this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 */

package org.eclipse.collections.impl.multimap;

import java.util.Map;

import org.eclipse.collections.api.RichIterable;
import org.eclipse.collections.api.bag.Bag;
import org.eclipse.collections.api.bag.MutableBag;
import org.eclipse.collections.api.block.function.Function;
import org.eclipse.collections.api.block.function.Function2;
import org.eclipse.collections.api.block.predicate.Predicate;
import org.eclipse.collections.api.block.predicate.Predicate2;
import org.eclipse.collections.api.block.procedure.Procedure;
import org.eclipse.collections.api.block.procedure.Procedure2;
import org.eclipse.collections.api.map.MapIterable;
import org.eclipse.collections.api.multimap.Multimap;
import org.eclipse.collections.api.multimap.MutableMultimap;
import org.eclipse.collections.api.tuple.Pair;
import org.eclipse.collections.impl.UnmodifiableRichIterable;
import org.eclipse.collections.impl.block.factory.Functions;
import org.eclipse.collections.impl.factory.Bags;
import org.eclipse.collections.impl.tuple.Tuples;

public abstract class AbstractMultimap>
        implements Multimap
{
    private static final Function, ?> CREATE_COLLECTION_BLOCK = new Function, RichIterable>()
    {
        public RichIterable valueOf(AbstractMultimap multimap)
        {
            return multimap.createCollection();
        }
    };

    protected abstract MapIterable getMap();

    /**
     * Creates the collection of values for a single key.
     * 

* Collections with weak, soft, or phantom references are not supported. * Each call to {@code createCollection} should create a new instance. *

* The returned collection class determines whether duplicate key-value * pairs are allowed. * * @return an empty collection of values */ protected abstract C createCollection(); protected Function, C> createCollectionBlock() { return (Function, C>) (Function) CREATE_COLLECTION_BLOCK; } // Query Operations public boolean containsKey(Object key) { return this.getMap().containsKey(key); } public boolean containsValue(final Object value) { return this.getMap().anySatisfy(new Predicate() { public boolean accept(C collection) { return collection.contains(value); } }); } public boolean containsKeyAndValue(Object key, Object value) { C collection = this.getMap().get(key); return collection != null && collection.contains(value); } // Views public RichIterable keysView() { return this.getMap().keysView(); } public RichIterable> multiValuesView() { return this.getMap().valuesView().collect(new Function>() { public RichIterable valueOf(C multiValue) { return UnmodifiableRichIterable.of(multiValue); } }); } public Bag keyBag() { final MutableBag bag = Bags.mutable.empty(); this.getMap().forEachKeyValue(new Procedure2() { public void value(K key, C value) { bag.addOccurrences(key, value.size()); } }); return bag; } public RichIterable valuesView() { return this.getMap().valuesView().flatCollect(Functions.>identity()); } public RichIterable>> keyMultiValuePairsView() { return this.getMap().keyValuesView().collect(new Function, Pair>>() { public Pair> valueOf(Pair pair) { return Tuples.>pair(pair.getOne(), UnmodifiableRichIterable.of(pair.getTwo())); } }); } public RichIterable> keyValuePairsView() { return this.keyMultiValuePairsView().flatCollect(new Function>, Iterable>>() { public Iterable> valueOf(Pair> pair) { return pair.getTwo().collect(new KeyValuePairFunction(pair.getOne())); } }); } // Comparison and hashing @Override public boolean equals(Object object) { if (object == this) { return true; } if (object instanceof Multimap) { Multimap that = (Multimap) object; return this.getMap().equals(that.toMap()); } return false; } /** * Returns the hash code for this multimap. *

* The hash code of a multimap is defined as the hash code of the map view, * as returned by {@link Multimap#toMap()}. * * @see Map#hashCode() */ @Override public int hashCode() { return this.getMap().hashCode(); } /** * Returns a string representation of the multimap, generated by calling * {@code toString} on the map returned by {@link Multimap#toMap()}. * * @return a string representation of the multimap */ @Override public String toString() { return this.getMap().toString(); } public boolean notEmpty() { return !this.isEmpty(); } public void forEachValue(final Procedure procedure) { this.getMap().forEachValue(new Procedure() { public void value(C collection) { collection.forEach(procedure); } }); } public void forEachKey(Procedure procedure) { this.getMap().forEachKey(procedure); } public void forEachKeyValue(final Procedure2 procedure) { final Procedure2 innerProcedure = new Procedure2() { public void value(V value, K key) { procedure.value(key, value); } }; this.getMap().forEachKeyValue(new Procedure2() { public void value(K key, C collection) { collection.forEachWith(innerProcedure, key); } }); } public void forEachKeyMultiValues(Procedure2> procedure) { this.getMap().forEachKeyValue(procedure); } public > R selectKeysValues(final Predicate2 predicate, final R target) { this.getMap().forEachKeyValue(new Procedure2() { public void value(final K key, C collection) { RichIterable selectedValues = collection.select(new Predicate() { public boolean accept(V value) { return predicate.accept(key, value); } }); target.putAll(key, selectedValues); } }); return target; } public > R rejectKeysValues(final Predicate2 predicate, final R target) { this.getMap().forEachKeyValue(new Procedure2() { public void value(final K key, C collection) { RichIterable selectedValues = collection.reject(new Predicate() { public boolean accept(V value) { return predicate.accept(key, value); } }); target.putAll(key, selectedValues); } }); return target; } public > R selectKeysMultiValues(final Predicate2> predicate, final R target) { this.forEachKeyMultiValues(new Procedure2>() { public void value(K key, Iterable collection) { if (predicate.accept(key, collection)) { target.putAll(key, collection); } } }); return target; } public > R rejectKeysMultiValues(final Predicate2> predicate, final R target) { this.forEachKeyMultiValues(new Procedure2>() { public void value(K key, Iterable collection) { if (!predicate.accept(key, collection)) { target.putAll(key, collection); } } }); return target; } private static final class KeyValuePairFunction implements Function> { private static final long serialVersionUID = 1L; private final K key; private KeyValuePairFunction(K key) { this.key = key; } public Pair valueOf(V value) { return Tuples.pair(this.key, value); } } public > R collectKeysValues(final Function2> function, final R target) { this.getMap().forEachKeyValue(new Procedure2() { public void value(final K key, C collection) { collection.forEach(new Procedure() { public void value(V value) { Pair pair = function.value(key, value); target.add(pair); } }); } }); return target; } public > R collectValues(final Function function, final R target) { this.getMap().forEachKeyValue(new Procedure2() { public void value(K key, C collection) { target.putAll(key, collection.collect(function)); } }); return target; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy