Description

Projects an immutable collection of this stream.

License

Open Source License

Return

An immutable collection of this stream.

Declaration

public static final <A> Collection<A> toLazyCollection(Stream<A> stream) 

Method Source Code

//package com.java2s;
//License from project: Open Source License 

import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;

import java.util.stream.Stream;

public class Main {
    /**//from ww w.j a  v  a2 s . co m
     * Projects an immutable collection of this stream. Initial iteration over the collection is not thread safe 
     * (can't be performed by multiple threads concurrently) subsequent iterations are.
     *
     * @return An immutable collection of this stream.
     */
    public static final <A> Collection<A> toLazyCollection(Stream<A> stream) {
        return toLazyCollection(stream.iterator());
    }

    public static final <A> Collection<A> toLazyCollection(
            Iterator<A> iterator) {
        return toLazyCollection(iterator, false);
    }

    private static final <A> Collection<A> toLazyCollection(
            Iterator<A> iterator, boolean concurrent) {
        return new AbstractCollection<A>() {

            @Override
            public boolean equals(Object o) {
                if (o == null)
                    return false;
                if (!(o instanceof Collection))
                    return false;
                Collection<A> c = (Collection) o;
                Iterator<A> it1 = iterator();
                Iterator<A> it2 = c.iterator();
                while (it1.hasNext()) {
                    if (!it2.hasNext())
                        return false;
                    if (!Objects.equals(it1.next(), it2.next()))
                        return false;
                }
                if (it2.hasNext())
                    return false;
                return true;
            }

            @Override
            public int hashCode() {
                Iterator<A> it1 = iterator();
                List<A> arrayList = new ArrayList<>();
                while (it1.hasNext()) {
                    arrayList.add(it1.next());
                }
                return Objects.hashCode(arrayList.toArray());
            }

            List<A> data = new ArrayList<>();

            volatile boolean complete = false;

            Object lock = new Object();
            ReentrantLock rlock = new ReentrantLock();

            public Iterator<A> iterator() {
                if (complete)
                    return data.iterator();
                return new Iterator<A>() {
                    int current = -1;

                    @Override
                    public boolean hasNext() {

                        if (concurrent) {

                            rlock.lock();
                        }
                        try {

                            if (current == data.size() - 1 && !complete) {
                                boolean result = iterator.hasNext();
                                complete = !result;

                                return result;
                            }
                            if (current + 1 < data.size()) {

                                return true;
                            }
                            return false;
                        } finally {
                            if (concurrent)
                                rlock.unlock();
                        }
                    }

                    @Override
                    public A next() {

                        if (concurrent) {

                            rlock.lock();
                        }
                        try {
                            if (current < data.size() && !complete) {
                                if (iterator.hasNext())
                                    data.add(iterator.next());

                                return data.get(++current);
                            }
                            current++;
                            return data.get(current);
                        } finally {

                            if (concurrent)
                                rlock.unlock();
                        }

                    }

                };

            }

            public int size() {
                if (complete)
                    return data.size();
                Iterator it = iterator();
                while (it.hasNext())
                    it.next();

                return data.size();
            }
        };
    }
}

Related

  1. lock()
  2. readSyncLock(String id)
  3. removeJavaStdLoggerHandlers()
  4. runConcurrent(long startGapTime, Runnable... tasks)
  5. runUnderLock(ReentrantLock lock, Runnable runnable)
  6. xor(byte[] a, byte[] b)