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

org.apache.commons.collections4.multimap.AbstractListValuedMap Maven / Gradle / Ivy

Go to download

The Apache Commons Collections package contains types that extend and augment the Java Collections Framework.

There is a newer version: 4.5.0-M1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.commons.collections4.multimap;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.apache.commons.collections4.ListUtils;
import org.apache.commons.collections4.ListValuedMap;

/**
 * Abstract implementation of the {@link ListValuedMap} interface to simplify
 * the creation of subclass implementations.
 * 

* Subclasses specify a Map implementation to use as the internal storage and * the List implementation to use as values. * * @param the type of the keys in this map * @param the type of the values in this map * @since 4.1 */ public abstract class AbstractListValuedMap extends AbstractMultiValuedMap implements ListValuedMap { /** * Constructor needed for subclass serialisation. */ protected AbstractListValuedMap() { super(); } /** * A constructor that wraps, not copies * * @param map the map to wrap, must not be null * @throws NullPointerException if the map is null */ protected AbstractListValuedMap(final Map> map) { super(map); } // ----------------------------------------------------------------------- @Override @SuppressWarnings("unchecked") protected Map> getMap() { return (Map>) super.getMap(); } /** * Creates a new value collection using the provided factory. * @return a new list */ @Override protected abstract List createCollection(); // ----------------------------------------------------------------------- /** * Gets the list of values associated with the specified key. This would * return an empty list in case the mapping is not present * * @param key the key to retrieve * @return the {@code List} of values, will return an empty {@link List} for no mapping */ @Override public List get(final K key) { return wrappedCollection(key); } @Override List wrappedCollection(final K key) { return new WrappedList(key); } /** * Removes all values associated with the specified key. *

* A subsequent get(Object) would return an empty list. * * @param key the key to remove values from * @return the List of values removed, will return an empty, * unmodifiable list for no mapping found. */ @Override public List remove(final Object key) { return ListUtils.emptyIfNull(getMap().remove(key)); } // ----------------------------------------------------------------------- /** * Wrapped list to handle add and remove on the list returned by get(object) */ private class WrappedList extends WrappedCollection implements List { public WrappedList(final K key) { super(key); } @Override protected List getMapping() { return getMap().get(key); } @Override public void add(final int index, final V value) { List list = getMapping(); if (list == null) { list = createCollection(); getMap().put(key, list); } list.add(index, value); } @Override public boolean addAll(final int index, final Collection c) { List list = getMapping(); if (list == null) { list = createCollection(); final boolean changed = list.addAll(index, c); if (changed) { getMap().put(key, list); } return changed; } return list.addAll(index, c); } @Override public V get(final int index) { final List list = ListUtils.emptyIfNull(getMapping()); return list.get(index); } @Override public int indexOf(final Object o) { final List list = ListUtils.emptyIfNull(getMapping()); return list.indexOf(o); } @Override public int lastIndexOf(final Object o) { final List list = ListUtils.emptyIfNull(getMapping()); return list.lastIndexOf(o); } @Override public ListIterator listIterator() { return new ValuesListIterator(key); } @Override public ListIterator listIterator(final int index) { return new ValuesListIterator(key, index); } @Override public V remove(final int index) { final List list = ListUtils.emptyIfNull(getMapping()); final V value = list.remove(index); if (list.isEmpty()) { AbstractListValuedMap.this.remove(key); } return value; } @Override public V set(final int index, final V value) { final List list = ListUtils.emptyIfNull(getMapping()); return list.set(index, value); } @Override public List subList(final int fromIndex, final int toIndex) { final List list = ListUtils.emptyIfNull(getMapping()); return list.subList(fromIndex, toIndex); } @Override public boolean equals(final Object other) { final List list = getMapping(); if (list == null) { return Collections.emptyList().equals(other); } if (!(other instanceof List)) { return false; } final List otherList = (List) other; return ListUtils.isEqualList(list, otherList); } @Override public int hashCode() { final List list = getMapping(); return ListUtils.hashCodeForList(list); } } /** Values ListIterator */ private class ValuesListIterator implements ListIterator { private final K key; private List values; private ListIterator iterator; public ValuesListIterator(final K key) { this.key = key; this.values = ListUtils.emptyIfNull(getMap().get(key)); this.iterator = values.listIterator(); } public ValuesListIterator(final K key, final int index) { this.key = key; this.values = ListUtils.emptyIfNull(getMap().get(key)); this.iterator = values.listIterator(index); } @Override public void add(final V value) { if (getMap().get(key) == null) { final List list = createCollection(); getMap().put(key, list); this.values = list; this.iterator = list.listIterator(); } this.iterator.add(value); } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public boolean hasPrevious() { return iterator.hasPrevious(); } @Override public V next() { return iterator.next(); } @Override public int nextIndex() { return iterator.nextIndex(); } @Override public V previous() { return iterator.previous(); } @Override public int previousIndex() { return iterator.previousIndex(); } @Override public void remove() { iterator.remove(); if (values.isEmpty()) { getMap().remove(key); } } @Override public void set(final V value) { iterator.set(value); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy