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

org.conqat.lib.commons.collections.SetMap Maven / Gradle / Ivy

There is a newer version: 2024.7.2
Show newest version
/*
 * Copyright (c) CQSE GmbH
 *
 * 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.conqat.lib.commons.collections;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

import org.conqat.lib.commons.assertion.CCSMAssert;

/**
 * Manages a map of sets, i.e. each key can store multiple elements.
 * 
 * @param 
 *            the key type.
 * @param 
 *            the value type (i.e. the values stored in the collections).
 */
public class SetMap extends CollectionMap> {

	/**
	 * Used to indicate which type of underlying set is used internally by the SetMap.
	 */
	public enum ESetFactory {
		HASHSET, IDENTITY_HASHSET
	}

	private static final long serialVersionUID = 1L;

	private final ESetFactory setFactory;

	public SetMap() {
		this(ESetFactory.HASHSET);
	}

	public SetMap(ESetFactory setFactory) {
		this.setFactory = setFactory;
	}

	@SafeVarargs
	public SetMap(SetMap... otherMaps) {
		this(determineFactory(otherMaps));
		for (SetMap otherMap : otherMaps) {
			addAll(otherMap);
		}
	}

	/** Copy constructor. */
	public SetMap(Map> other) {
		this();
		addAll(other);
	}

	private static  ESetFactory determineFactory(SetMap[] otherMaps) {
		if (otherMaps.length > 0) {
			return otherMaps[0].setFactory;
		}
		return ESetFactory.HASHSET;
	}

	@SafeVarargs
	public SetMap(Map>... otherMaps) {
		this();
		for (Map> otherMap : otherMaps) {
			addAll(otherMap);
		}
	}

	@Override
	protected Set createNewCollection() {
		switch (setFactory) {
		case HASHSET:
			return new HashSet<>();
		case IDENTITY_HASHSET:
			return new IdentityHashSet<>();
		default:
			throw new AssertionError();
		}
	}

	/** Inverts this SetMap, i.e. switches the keys and values. */
	public SetMap invert() {
		SetMap invertedMap = new SetMap<>();
		for (K nowValue : getKeys()) {
			for (V nowKey : getCollectionOrEmpty(nowValue)) {
				invertedMap.add(nowKey, nowValue);
			}
		}
		return invertedMap;
	}

	/**
	 * Applies the {@code mapper} to every key in this instance, and provides the result as a new
	 * {@link SetMap}.
	 * 

* If multiple keys are mapped to the same key, the values are combined. * * @param mapper * Maps old keys to new keys. * @param * new key type * @return A new {@link SetMap} with the converted values. * @implNote The {@link #setFactory} is preserved in the created instance. */ public SetMap mapKeys(Function mapper) { CCSMAssert.isNotNull(mapper, () -> String.format("Expected \"%s\" to be not null", "mapper")); SetMap result = new SetMap<>(setFactory); for (Map.Entry> entry : this) { K2 key = mapper.apply(entry.getKey()); result.addAll(key, entry.getValue()); } return result; } /** * Applies the {@code mapper} to every value in this instance, and provides the result as a new * {@link SetMap}. * * @param mapper * Maps old values to new values. * @param * new value type * @return A new {@link SetMap} with the converted values. * @implNote The {@link #setFactory} is preserved in the created instance. */ public SetMap mapValues(Function mapper) { CCSMAssert.isNotNull(mapper, () -> String.format("Expected \"%s\" to be not null", "mapper")); SetMap result = new SetMap<>(setFactory); for (Map.Entry> entry : this) { K key = entry.getKey(); for (V value : entry.getValue()) { result.add(key, mapper.apply(value)); } } return result; } /** Factory function for a {@link SetMap} with one entry. */ public static SetMap of(K key, V... values) { SetMap result = new SetMap<>(); result.addAll(key, Arrays.asList(values)); return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy