/*
* Copyright 2003-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.mps.util;
import org.jetbrains.mps.util.Condition;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* @author Kostik
*/
public class CollectionUtil {
public static <T, F extends T> List<F> filter(Class<F> cls, List<? extends T> l) {
List<F> result = new ArrayList<F>();
for (T t : l) {
if (cls.isInstance(t)) {
result.add(cls.cast(t));
}
}
return result;
}
public static <T, F extends T> Set<F> filter(Class<F> cls, Set<? extends T> s) {
Set<F> result = new LinkedHashSet<F>();
for (T t : s) {
if (cls.isInstance(t)) {
result.add(cls.cast(t));
}
}
return result;
}
@Deprecated
//use Iterable & ConditionalIterable instead
public static <T> List<T> filter(List<? extends T> ts, Condition<T> f) {
List<T> result = new ArrayList<T>();
for (T t : ts) {
if (f.met(t)) {
result.add(t);
}
}
return result;
}
@Deprecated
//use Iterable & ConditionalIterable instead
public static <T> Set<T> filter(Set<T> ts, Condition<T> f) {
Set<T> result = new HashSet<T>();
for (T t : ts) {
if (f.met(t)) {
result.add(t);
}
}
return result;
}
public static <T> Set<T> union(Set<T>... sets) {
Set<T> result = new LinkedHashSet<T>();
for (Set<T> s : sets) {
result.addAll(s);
}
return result;
}
public static <T> List<T> union(List<T>... sets) {
List<T> result = new ArrayList<T>();
for (List<T> s : sets) {
result.addAll(s);
}
return result;
}
public static <T> Set<T> set(T... ts) {
Set<T> result = new HashSet<T>();
result.addAll(Arrays.asList(ts));
return result;
}
public static <T> Iterator<T> concat(final Iterator<? extends T> it1, final Iterator<? extends T> it2) {
return new Iterator<T>() {
public boolean myFirstActive = true;
@Override
public boolean hasNext() {
if (myFirstActive) {
if (it1.hasNext()) {
return true;
} else {
myFirstActive = false;
return it2.hasNext();
}
} else {
return it2.hasNext();
}
}
@Override
public T next() {
if (myFirstActive) {
if (it1.hasNext()) {
return it1.next();
} else {
myFirstActive = false;
return it2.next();
}
} else {
return it2.next();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static <T> void addMissing(Collection<T> fromCollection, Collection<T> toCollection) {
for (T t : fromCollection) {
if (!toCollection.contains(t)) {
toCollection.add(t);
}
}
}
public static <T> List<T> subtract(Collection<T> fromCollection, Collection<T> collection) {
ArrayList<T> result = new ArrayList<T>();
for (T t : fromCollection) {
if (!collection.contains(t)) {
result.add(t);
}
}
return result;
}
public static <T> List<T> intersect(Collection<T> collection1, Collection<T> collection2) {
if (collection2.isEmpty() || collection1.isEmpty()) {
return Collections.emptyList();
}
ArrayList<T> result = new ArrayList<T>(Math.min(collection1.size(), collection2.size()));
for (T t : collection1) {
if (collection2.contains(t)) {
result.add(t);
}
}
return result;
}
public static <T> boolean intersects(Collection<T> collection1, Collection<T> collection2) {
if (collection2.isEmpty() || collection1.isEmpty()) {
return false;
}
for (T t : collection1) {
if (collection2.contains(t)) {
return true;
}
}
return false;
}
public static <T> Iterable<T> withoutNulls(final Iterable<T> resultList) {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return new SkipNullIterator<T>(resultList.iterator());
}
};
}
private static class SkipNullIterator<Item> implements Iterator<Item> {
private Iterator<Item> mySourceIterator;
private Item myLookup = null;
public SkipNullIterator(Iterator<Item> iter) {
mySourceIterator = iter;
}
@Override
public boolean hasNext() {
if (myLookup != null) return true;
while (mySourceIterator.hasNext()) {
myLookup = mySourceIterator.next();
if (myLookup != null) {
return true;
}
}
return false;
}
@Override
public Item next() {
while (myLookup == null) {
myLookup = mySourceIterator.next();
}
Item result = myLookup;
myLookup = null;
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
public static void main(String[] args) {
Iterable<String> it1 = Arrays.asList("5", "6", "7", "8");
Iterable<String> it2 = Arrays.asList("5", null, "6", null, "7", "8");
Iterable<String> it3 = Arrays.asList("5", null, "6", "7", "8", null, null);
Iterable<String> it4 = Arrays.asList(new String[] { null });
Iterable<String> it5 = Arrays.asList(null, null);
Iterable<String> it6 = Arrays.asList(null, null, null);
Iterable<String> it7 = Arrays.asList();
printWithoutNulls(it1);
printWithoutNulls(it2);
printWithoutNulls(it3);
printWithoutNulls(it4);
printWithoutNulls(it5);
printWithoutNulls(it6);
printWithoutNulls(it7);
}
private static void printWithoutNulls(Iterable it) {
System.err.println();
System.err.print("it = (");
Iterable iterable = withoutNulls(it);
for (Object elem : iterable) {
System.err.print(elem);
System.err.print(",");
}
System.err.println(")");
}
}