简体   繁体   中英

A collection that represents a concatenation of two collections in Java

Is there a class that represents the concatenation of a collection with another collection? This class should be a Collection in itself, and should delegate all methods to the underlying (inner) collections - no extra memory should be allocated, nor any of the original collections modified.

Example usage:

Collection<String> foo = ...
Collection<String> bar = ...

// this should be O(1) memory and time
Collection<String> combined = concat(foo, bar);

if (combined.contains("Zee"))
  ...

for (String str : combined)
  System.out.println(str);

As always for any collections stuff, look at google-collections . If you have Set s, specifically (not just a general collection), you want:

Set<String> combined = Sets.union(foo, bar);

which creates an unmodifiable view of the two sets. That is, changes in foo or bar will be reflected in combined (but combined.add() etc is not supported).

For the more generic case, you have Iterables.concat() but that merely lets you iterate over the joined item, the Iterable interface obviously doesn't include contains so you're a little hosed there.

The other collections utilities classes in google-collections ( com.google.common.collect.Lists and com.google.common.collect.Collections2 ) don't contain any concatenation methods. Don't see why they couldn't, but at the moment they don't.

Your question is very vague. Especially "with another item another collection" is quite unclear.

You can at least add the contents of another Collection to the current Collection using Collection#addAll() . Here Collection can be anything of its subinterfaces/implementations, eg List or Set .

Example:

List<String> foos = Arrays.asList("foo1", "foo2", "foo3");
List<String> bars = Arrays.asList("bar1", "bar2", "bar3");
foos.addAll(bars); // Now foos contains everything.

Edit : Or do you actually want to create a new Collection based on an existing Collection and then add a new item to it? In this case just construct a new Collection with the existing Collection as constructor argument. Eg:

List<String> foos = Arrays.asList("foo1", "foo2", "foo3");
List<String> bars = new ArrayList<String>(foos);
bars.add("bar"); // Now bars contains everything.

There is not, but writing it yourself should be straight forward

package ch.akuhn.util;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Concat {

    public static <T> Iterable<T> all(final Iterable<T>... iterables) {
        return new Iterable<T>() {
            @Override
            public Iterator<T> iterator() {
                return new Iterator<T>() {
                    Iterator<Iterable<T>> more = Arrays.asList(iterables).iterator();
                    Iterator<T> current = more.hasNext() ? more.next().iterator() : null;
                    @Override
                    public boolean hasNext() {
                        if (current == null) return false;
                        if (current.hasNext()) return true;
                        current = more.hasNext() ? more.next().iterator() : null;
                        return this.hasNext();
                    }

                    @Override
                    public T next() {
                        if (!hasNext()) throw new NoSuchElementException();
                        return current.next();
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }

}

And then

for (Object each: Concat.all(collection,whatever,etcetera,...)) {
    // ...
}

Just wrote this code here, compile at your own risk!

PS, if you gonna write unit tests for this class, send 'em to me.

I think what you're asking for is a Java construct that allows you to put collections together without modifying the original collections. In other words, you have collections A and B, both of size N and M respectively. After the concat call, you still have collections A and B and their sizes are still N and M, however you have collection C as well which points to A and B, making its size N+M.

The answer is no, Java doesn't have anything out of the box that does this... However you could write a quick wrapper that wraps a series of collections and add those collections to it. (All it would do is maintain references to each of the collections) and you could expose get/insert methods as needed.

Apache Commons Collections还有一个更通用的CompositeCollection类,可以用作任意数量Collection的接口。

I'm not sure what your asking. My interpretation of your question is that your looking for the add method on the Collection. I don't think that's what you're asking though.

尝试InterleavingEnumeration或apache的commons集合' ListUtils (ListUtils.union())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM