com.github.jonross.seq4j.SeqMisc.java Source code

Java tutorial

Introduction

Here is the source code for com.github.jonross.seq4j.SeqMisc.java

Source

/*
 * Copyright (c) 2012, Jonathan Ross <jonross@alum.mit.edu>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

package com.github.jonross.seq4j;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.collect.Sets;

/**
 * Assorted {@link Function Functions} and {@link Predicate Predicates} for applying to
 * sequences.  These and Guava functions / predicates can be imported individually, or via
 * {@link Fns} all of those in Seq4J and most from Guava can be imported in one statement.
 */

public class SeqMisc {
    /**
     * Returns a function that adds its argument to the given collection.
     */

    public static <T> Function<T, Void> addTo(final Collection<T> collection) {
        return new Function<T, Void>() {
            public Void apply(T arg) {
                collection.add(arg);
                return null;
            }
        };
    }

    /**
     * Returns a function that adds its argument to a map, using a supplied function
     * to determine the key.
     * 
     * @param map The map to modify
     * @param keyBuilder A function to determine a key for each value
     * @return A new function that adds its argument to <code>map</code> by using
     * <code>keyBuilder.apply(argument)</code> to determine the key. 
     */

    public static <T, K> Function<T, Void> addTo(final Map<K, T> map,
            final Function<? super T, ? extends K> keyMaker) {
        return new Function<T, Void>() {
            public Void apply(T arg) {
                map.put(keyMaker.apply(arg), arg);
                return null;
            }
        };
    }

    /**
     * Wraps {@link Functions#forMap(Map)}; returns a function that looks up its
     * argument in a map.
     */

    public static <K, V> Function<K, V> lookup(Map<K, V> map) {
        return Functions.forMap(map);
    }

    /**
     * Wraps {@link Functions#forMap(Map, Object)}; returns a function that looks up its
     * argument in a map, using the given default value if the map does not contain that key.
     */

    public static <K, V> Function<K, V> lookup(Map<K, ? extends V> map, V defaultValue) {
        return Functions.forMap(map, defaultValue);
    }

    /**
     * Returns a stateful predicate that returns true if its argument has been passed
     * to the predicate before, else false.
     */

    public static Predicate<Object> unique() {
        return new Predicate<Object>() {
            private Set<Object> seen = Sets.newHashSet();
            private boolean sawNull = false;

            public boolean apply(Object arg) {
                if (arg == null) {
                    boolean result = !sawNull;
                    sawNull = true;
                    return result;
                } else if (seen.contains(arg)) {
                    return false;
                } else {
                    seen.add(arg);
                    return true;
                }
            }
        };
    }

}