001/*
002 * ModeShape (http://www.modeshape.org)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *       http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.modeshape.common.collection;
017
018import java.util.Arrays;
019import java.util.Collection;
020import java.util.HashSet;
021import java.util.Iterator;
022import java.util.Set;
023
024/**
025 * A set of utilities for more easily creating various kinds of collections.
026 */
027public class Collections {
028
029    @SafeVarargs
030    public static <T> Set<T> unmodifiableSet(T... values ) {
031        return unmodifiableSet(Arrays.asList(values));
032    }
033
034    public static <T> Set<T> unmodifiableSet( Collection<T> values ) {
035        return java.util.Collections.unmodifiableSet(new HashSet<>(values));
036    }
037
038    public static <T> Set<T> unmodifiableSet( Set<T> values ) {
039        return java.util.Collections.unmodifiableSet(values);
040    }
041
042    private Collections() {
043    }
044
045    /**
046     * Concatenate two Iterable sources
047     * 
048     * @param a a non-null Iterable value
049     * @param b a non-null Iterable value
050     * @return an Iterable that will iterate through all the values from 'a' and then all the values from 'b'
051     * @param <T> the value type
052     */
053    public static <T> Iterable<T> concat( final Iterable<T> a,
054                                          final Iterable<T> b ) {
055        assert (a != null);
056        assert (b != null);
057        return () -> Collections.concat(a.iterator(), b.iterator());
058
059    }
060
061    /**
062     * Concatenate two Iterators
063     * 
064     * @param a a non-null Iterator
065     * @param b a non-null Iterator
066     * @return an Iterator that will iterate through all the values of 'a', and then all the values of 'b'
067     * @param <T> the value type
068     */
069    public static <T> Iterator<T> concat( final Iterator<T> a,
070                                          final Iterator<T> b ) {
071        assert (a != null);
072        assert (b != null);
073
074        return new Iterator<T>() {
075
076            @Override
077            public boolean hasNext() {
078                return a.hasNext() || b.hasNext();
079            }
080
081            @Override
082            public T next() {
083                if (a.hasNext()) {
084                    return a.next();
085                }
086
087                return b.next();
088            }
089
090            @Override
091            public void remove() {
092                throw new UnsupportedOperationException();
093            }
094        };
095    }
096}