001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.internal; 018 019import java.util.*; 020 021import org.apache.juneau.common.utils.*; 022 023/** 024 * Encapsulates multiple collections so they can be iterated over as if they were all part of the same collection. 025 * 026 * <h5 class='section'>See Also:</h5><ul> 027 028 * </ul> 029 * 030 * @param <E> The object type of this set. 031 */ 032public class MultiSet<E> extends AbstractSet<E> { 033 034 /** Inner collections. */ 035 final Collection<E>[] l; 036 037 /** 038 * Create a new Set that consists as a coalesced set of the specified collections. 039 * 040 * @param c Zero or more collections to add to this set. 041 */ 042 @SafeVarargs 043 public MultiSet(Collection<E>...c) { 044 Utils.assertArgNotNull("c", c); 045 for (Collection<E> cc : c) 046 Utils.assertArgNotNull("c", cc); 047 l = c; 048 } 049 050 /** 051 * Iterates over all entries in all collections. 052 */ 053 @Override /* Set */ 054 public Iterator<E> iterator() { 055 return new Iterator<>() { 056 int i = 0; 057 Iterator<E> i2 = (l.length > 0 ? l[i++].iterator() : null); 058 059 @Override /* Iterator */ 060 public boolean hasNext() { 061 if (i2 == null) 062 return false; 063 if (i2.hasNext()) 064 return true; 065 for (int j = i; j < l.length; j++) 066 if (l[j].size() > 0) 067 return true; 068 return false; 069 } 070 071 @Override /* Iterator */ 072 public E next() { 073 if (i2 == null) 074 throw new NoSuchElementException(); 075 while (! i2.hasNext()) { 076 if (i >= l.length) 077 throw new NoSuchElementException(); 078 i2 = l[i++].iterator(); 079 } 080 return i2.next(); 081 } 082 083 @Override /* Iterator */ 084 public void remove() { 085 if (i2 == null) 086 throw new NoSuchElementException(); 087 i2.remove(); 088 } 089 }; 090 } 091 092 /** 093 * Enumerates over all entries in all collections. 094 * 095 * @return An enumeration wrapper around this set. 096 */ 097 public Enumeration<E> enumerator() { 098 return Collections.enumeration(this); 099 } 100 101 @Override /* Set */ 102 public int size() { 103 int i = 0; 104 for (Collection<E> c : l) 105 i += c.size(); 106 return i; 107 } 108}