001package conexp.fx.core.collections; 002 003import java.io.BufferedWriter; 004import java.io.File; 005import java.io.FileWriter; 006import java.io.IOException; 007 008/* 009 * #%L 010 * Concept Explorer FX 011 * %% 012 * Copyright (C) 2010 - 2019 Francesco Kriegel 013 * %% 014 * This program is free software: you can redistribute it and/or modify 015 * it under the terms of the GNU General Public License as 016 * published by the Free Software Foundation, either version 3 of the 017 * License, or (at your option) any later version. 018 * 019 * This program is distributed in the hope that it will be useful, 020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 022 * GNU General Public License for more details. 023 * 024 * You should have received a copy of the GNU General Public 025 * License along with this program. If not, see 026 * <http://www.gnu.org/licenses/gpl-3.0.html>. 027 * #L% 028 */ 029 030import java.util.AbstractCollection; 031import java.util.AbstractList; 032import java.util.AbstractSet; 033import java.util.ArrayList; 034import java.util.Arrays; 035import java.util.Collection; 036import java.util.Collections; 037import java.util.Comparator; 038import java.util.Iterator; 039import java.util.List; 040import java.util.NoSuchElementException; 041import java.util.Random; 042import java.util.Set; 043import java.util.concurrent.ConcurrentHashMap; 044import java.util.function.BiPredicate; 045import java.util.function.Supplier; 046import java.util.stream.Collectors; 047 048import com.google.common.base.Function; 049import com.google.common.base.Predicate; 050import com.google.common.base.Predicates; 051import com.google.common.collect.Collections2; 052import com.google.common.collect.Iterables; 053import com.google.common.collect.Iterators; 054import com.google.common.collect.Lists; 055 056import conexp.fx.core.math.GuavaIsomorphism; 057 058public final class Collections3 { 059 060 public static final <E> Set<Set<E>> quotient(final Set<E> set, BiPredicate<E, E> pred) { 061 return set 062 .parallelStream() 063 .map(x -> set.parallelStream().filter(y -> pred.test(x, y)).collect(Collectors.toSet())) 064 .collect(Collectors.toSet()); 065 } 066 067 public static final <E> Set<E> representatives(final Set<E> set, BiPredicate<E, E> pred) { 068 return quotient(set, pred).parallelStream().map(eqclass -> eqclass.iterator().next()).collect(Collectors.toSet()); 069 } 070 071 public static final <E> Set<E> newConcurrentHashSet() { 072 return Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>()); 073 } 074 075 public static final BitSetFX integers(final int n) { 076// return Stream.iterate(0, k -> k + 1).limit(n).collect(Collectors.toSet()); 077 final BitSetFX s = new BitSetFX(); 078 s.addRange(0, n); 079 return s; 080 } 081 082 public static final <E extends Number & Comparable<E>> double sum(final Collection<? extends E> c) { 083 double s = 0d; 084 for (E e : c) 085 s += e.doubleValue(); 086 return s; 087 } 088 089 public static final <E extends Number & Comparable<E>> double avg(final Collection<? extends E> c) { 090 return sum(c) / (double) c.size(); 091 } 092 093 public static final <E> Collection<E> union(final Collection<Collection<E>> c) { 094 return new AbstractCollection<E>() { 095 096 public final Iterator<E> iterator() { 097 return Iterables.concat(c).iterator(); 098 } 099 100 public final int size() { 101 int size = 0; 102 for (Collection<? extends E> _c : c) 103 size += _c.size(); 104 return size; 105 } 106 }; 107 } 108 109 @SafeVarargs 110 public static final <E> Collection<E> union(final Collection<E>... c) { 111 return union(Arrays.asList(c)); 112 } 113 114 public static final <E> Collection<E> union(final Collection<? extends E> c1, final Collection<? extends E> c2) { 115 return new AbstractCollection<E>() { 116 117 public final Iterator<E> iterator() { 118 return Iterators.concat(c1.iterator(), c2.iterator()); 119 } 120 121 public final int size() { 122 return c1.size() + c2.size(); 123 } 124 }; 125 } 126 127 public static final <E> Collection<E> intersection(final Collection<E> c1, final Collection<? extends E> c2) { 128 return Collections2.filter(c1, Predicates.in(c2)); 129 } 130 131 public static final <E> Collection<E> difference(final Collection<E> c1, final Collection<? extends E> c2) { 132 return Collections2.<E> filter(c1, Predicates.not(Predicates.in(c2))); 133 } 134 135 public static final <T, E> Set<E> transform(final Set<T> s, final GuavaIsomorphism<T, E> f) { 136 return new AbstractSet<E>() { 137 138 @Override 139 public final Iterator<E> iterator() { 140 return Iterators.transform(s.iterator(), f); 141 } 142 143 @Override 144 public final int size() { 145 return s.size(); 146 } 147 }; 148 } 149 150 public static final <E> E random(final Collection<? extends E> c, final Random rng) { 151 if (c.isEmpty()) 152 throw new NoSuchElementException(); 153 final int i = rng.nextInt(c.size()); 154 if (c instanceof List) { 155 final List<? extends E> l = (List<? extends E>) c; 156 return l.get(i); 157 } 158 int j = 0; 159 for (E e : c) 160 if (j++ == i) 161 return e; 162 throw new NoSuchElementException(); 163 } 164 165 public static final <E> E random(final Collection<? extends E> c, final Predicate<E> p, final Random rng) { 166 E e; 167 while (true) { 168 e = random(c, rng); 169 if (p.apply(e)) 170 break; 171 } 172 return e; 173 } 174 175 public static final <E extends Comparable<E>> List<E> sort(final Iterable<? extends E> i) { 176 final ArrayList<E> l = Lists.newArrayList(i); 177 Collections.sort(l); 178 return l; 179 } 180 181 public static final <E> List<E> sort(final Iterable<? extends E> i, final Comparator<? super E> c) { 182 final ArrayList<E> l = Lists.newArrayList(i); 183 Collections.sort(l, c); 184 return l; 185 } 186 187 public static final <E, T extends E> Collection<T> elementsBySubClass(final Collection<E> c, final Class<T> clazz) { 188 return Collections2.transform(Collections2.filter(c, Predicates.instanceOf(clazz)), new Function<E, T>() { 189 190 public final T apply(final E e) { 191 return clazz.cast(e); 192 } 193 }); 194 } 195 196 public static final <E> Function<Set<E>, Iterator<E>> setToIterator() { 197 return new Function<Set<E>, Iterator<E>>() { 198 199 public final Iterator<E> apply(final Set<E> it) { 200 return it.iterator(); 201 } 202 }; 203 } 204 205 public static final <E> Set<E> fromIterator(final Supplier<Iterator<E>> its) { 206 return new AbstractSet<E>() { 207 208 @Override 209 public Iterator<E> iterator() { 210 return its.get(); 211 } 212 213 @Override 214 public int size() { 215 return Iterators.size(iterator()); 216 } 217 }; 218 } 219 220 public static final <E> Iterable<E> iterable(final Iterator<E> it) { 221 return new Iterable<E>() { 222 223 @Override 224 public Iterator<E> iterator() { 225 return it; 226 } 227 }; 228 } 229 230 public static final Predicate<Integer> isSmaller(final int n) { 231 return new Predicate<Integer>() { 232 233 public final boolean apply(final Integer m) { 234 return m < n; 235 } 236 }; 237 } 238 239 public static final <E> E firstElement(final Iterable<E> it) { 240 return it.iterator().next(); 241 } 242 243 public static final <E> Function<Iterable<E>, E> firstElement() { 244 return new Function<Iterable<E>, E>() { 245 246 public final E apply(final Iterable<E> it) { 247 return it.iterator().next(); 248 } 249 }; 250 } 251 252// public static final BitSetSetFX newBitSetSet(final Collection<Integer> c) { 253// final BitSetSetFX b = new BitSetSetFX(); 254// b.addAll(c); 255// return b; 256// } 257 258// public static final BitSetSet2 newBitSetSet2(final Collection<Integer> c) { 259// final BitSetSet2 b = new BitSetSet2(); 260// b.addAll(c); 261// return b; 262// } 263 264 public static final <E> List<E> filter(final List<E> l, final Predicate<E> p) { 265 return new AbstractList<E>() { 266 267 public final E get(final int index) { 268 return Iterables.get(Iterables.filter(l, p), index); 269 } 270 271 public final int size() { 272 return Iterables.size(Iterables.filter(l, p)); 273 } 274 }; 275 } 276 277 public static final <T> void 278 writeToFile(final File file, final Collection<T> collection, final String prefix, final String... suffix) 279 throws IOException { 280 final BufferedWriter writer = new BufferedWriter(new FileWriter(file)); 281 writer.append(prefix); 282 writer.append("size: " + collection.size()); 283 // collection.stream().map(T::toString).forEach(bw::append); 284 for (T element : collection) 285 writer.append(element.toString()); 286 if (suffix.length > 0) 287 writer.append(suffix[0]); 288 writer.close(); 289 } 290}