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

org.codehaus.plexus.util.CollectionUtils Maven / Gradle / Ivy

There is a newer version: 4.0.0-alpha-5
Show newest version
package org.codehaus.plexus.util;

/*
 * Copyright The Codehaus Foundation.
 *
 * 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.
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

/**
 * @author olamy
 *
 */
public class CollectionUtils
{
    // ----------------------------------------------------------------------
    // Static methods that can probably be moved to a real util class.
    // ----------------------------------------------------------------------

    /**
     * Take a dominant and recessive Map and merge the key:value pairs where the recessive Map may add key:value pairs
     * to the dominant Map but may not override any existing key:value pairs. If we have two Maps, a dominant and
     * recessive, and their respective keys are as follows: dominantMapKeys = { a, b, c, d, e, f } recessiveMapKeys = {
     * a, b, c, x, y, z } Then the result should be the following: resultantKeys = { a, b, c, d, e, f, x, y, z }
     *
     * @param dominantMap Dominant Map.
     * @param recessiveMap Recessive Map.
     * @param  type
     * @param  type
     * @return The result map with combined dominant and recessive values.
     */
    public static  Map mergeMaps( Map dominantMap, Map recessiveMap )
    {

        if ( dominantMap == null && recessiveMap == null )
        {
            return null;
        }

        if ( dominantMap != null && recessiveMap == null )
        {
            return dominantMap;
        }

        if ( dominantMap == null )
        {
            return recessiveMap;
        }

        Map result = new HashMap<>();

        // Grab the keys from the dominant and recessive maps.
        Set dominantMapKeys = dominantMap.keySet();
        Set recessiveMapKeys = recessiveMap.keySet();

        // Create the set of keys that will be contributed by the
        // recessive Map by subtracting the intersection of keys
        // from the recessive Map's keys.
        Collection contributingRecessiveKeys =
            CollectionUtils.subtract( recessiveMapKeys,
                                      CollectionUtils.intersection( dominantMapKeys, recessiveMapKeys ) );

        result.putAll( dominantMap );

        // Now take the keys we just found and extract the values from
        // the recessiveMap and put the key:value pairs into the dominantMap.
        for ( K key : contributingRecessiveKeys )
        {
            result.put( key, recessiveMap.get( key ) );
        }

        return result;
    }

    /**
     * Take a series of Maps and merge them where the ordering of the array from 0..n is the dominant
     * order.
     *
     * @param maps An array of Maps to merge.
     * @param  type
     * @param  type
     * @return Map The result Map produced after the merging process.
     */
    public static  Map mergeMaps( Map[] maps )
    {
        Map result;

        if ( maps.length == 0 )
        {
            result = null;
        }
        else if ( maps.length == 1 )
        {
            result = maps[0];
        }
        else
        {
            result = mergeMaps( maps[0], maps[1] );

            for ( int i = 2; i < maps.length; i++ )
            {
                result = mergeMaps( result, maps[i] );
            }
        }

        return result;
    }

    /**
     * 

* Returns a {@link Collection} containing the intersection of the given {@link Collection}s. *

* The cardinality of each element in the returned {@link Collection} will be equal to the minimum of the * cardinality of that element in the two given {@link Collection}s. * * @param a The first collection * @param b The second collection * @param the type * @see Collection#retainAll * @return The intersection of a and b, never null */ public static Collection intersection( final Collection a, final Collection b ) { ArrayList list = new ArrayList<>(); Map mapa = getCardinalityMap( a ); Map mapb = getCardinalityMap( b ); Set elts = new HashSet<>( a ); elts.addAll( b ); for ( E obj : elts ) { for ( int i = 0, m = Math.min( getFreq( obj, mapa ), getFreq( obj, mapb ) ); i < m; i++ ) { list.add( obj ); } } return list; } /** * Returns a {@link Collection} containing a - b. The cardinality of each element e in * the returned {@link Collection} will be the cardinality of e in a minus the cardinality of e * in b, or zero, whichever is greater. * * @param a The start collection * @param b The collection that will be subtracted * @param the type * @see Collection#removeAll * @return The result of the subtraction */ public static Collection subtract( final Collection a, final Collection b ) { ArrayList list = new ArrayList<>( a ); for ( T aB : b ) { list.remove( aB ); } return list; } /** * Returns a {@link Map} mapping each unique element in the given {@link Collection} to an {@link Integer} * representing the number of occurrences of that element in the {@link Collection}. An entry that maps to * null indicates that the element does not appear in the given {@link Collection}. * * @param col The collection to count cardinalities for * @param the type * @return A map of counts, indexed on each element in the collection */ public static Map getCardinalityMap( final Collection col ) { HashMap count = new HashMap<>(); for ( E obj : col ) { Integer c = count.get( obj ); if ( null == c ) { count.put( obj, 1 ); } else { count.put( obj, c + 1 ); } } return count; } public static List iteratorToList( Iterator it ) { if ( it == null ) { throw new NullPointerException( "it cannot be null." ); } List list = new ArrayList(); while ( it.hasNext() ) { list.add( it.next() ); } return list; } // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- private static int getFreq( final E obj, final Map freqMap ) { try { Integer o = freqMap.get( obj ); if ( o != null ) // minimize NullPointerExceptions { return o; } } catch ( NullPointerException | NoSuchElementException ignore ) { } return 0; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy