diff --git a/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/Lists.java b/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/Lists.java index 4dcf00dbe8..f5a1143919 100644 --- a/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/Lists.java +++ b/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/Lists.java @@ -1,8 +1,11 @@ package aQute.bnd.unmodifiable; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collector; @SuppressWarnings("unchecked") public class Lists { @@ -71,4 +74,11 @@ public static List copyOf(Collection collection) { } return new ImmutableList(collection.toArray()); } + + public static Collector> toList() { + return Collector.of((Supplier>) ArrayList::new, List::add, (l, r) -> { + l.addAll(r); + return l; + }, Lists::copyOf); + } } diff --git a/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/Sets.java b/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/Sets.java index 7ee4c96cf6..0718cea219 100644 --- a/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/Sets.java +++ b/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/Sets.java @@ -2,7 +2,10 @@ import java.util.Arrays; import java.util.Collection; +import java.util.LinkedHashSet; import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collector; @SuppressWarnings("unchecked") public class Sets { @@ -76,4 +79,11 @@ public static Set copyOf(Collection collection) { .distinct() .toArray()); } + + public static Collector> toSet() { + return Collector.of((Supplier>) LinkedHashSet::new, Set::add, (l, r) -> { + l.addAll(r); + return l; + }, Sets::copyOf); + } } diff --git a/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/package-info.java b/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/package-info.java index 3adc7df466..934610213e 100644 --- a/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/package-info.java +++ b/biz.aQute.bnd.util/src/aQute/bnd/unmodifiable/package-info.java @@ -1,4 +1,4 @@ -@Version("2.0.0") +@Version("2.1.0") package aQute.bnd.unmodifiable; import org.osgi.annotation.versioning.Version; diff --git a/biz.aQute.bnd.util/test/aQute/bnd/unmodifiable/ListsTest.java b/biz.aQute.bnd.util/test/aQute/bnd/unmodifiable/ListsTest.java index 364d1d4db2..04d8ef4373 100644 --- a/biz.aQute.bnd.util/test/aQute/bnd/unmodifiable/ListsTest.java +++ b/biz.aQute.bnd.util/test/aQute/bnd/unmodifiable/ListsTest.java @@ -550,4 +550,23 @@ public void spliterator() throws Exception { Spliterator.SUBSIZED, Spliterator.NONNULL); } + @Test + public void collector() { + List source = new ArrayList<>(); + source.add("e1"); + source.add("e2"); + source.add("e1"); + List list = source.stream() + .collect(Lists.toList()); + source.set(0, "changed"); + assertThat(list).hasSize(3) + .containsExactly("e1", "e2", "e1"); + assertThat(list.stream()).hasSize(3) + .containsExactly("e1", "e2", "e1"); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> list.add("a")); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> list.remove("a")); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> list.remove("e1")); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> list.clear()); + } + } diff --git a/biz.aQute.bnd.util/test/aQute/bnd/unmodifiable/SetsTest.java b/biz.aQute.bnd.util/test/aQute/bnd/unmodifiable/SetsTest.java index ca6aa9027e..4bc817d399 100644 --- a/biz.aQute.bnd.util/test/aQute/bnd/unmodifiable/SetsTest.java +++ b/biz.aQute.bnd.util/test/aQute/bnd/unmodifiable/SetsTest.java @@ -40,7 +40,7 @@ public void zero() { public void one() { Set set = Sets.of("e1"); assertThat(set).hasSize(1) - .containsExactlyInAnyOrder("e1"); + .containsExactly("e1"); assertThat(set.stream()).hasSize(1) .containsExactly("e1"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -53,7 +53,7 @@ public void one() { public void two() { Set set = Sets.of("e1", "e2"); assertThat(set).hasSize(2) - .containsExactlyInAnyOrder("e1", "e2"); + .containsExactly("e1", "e2"); assertThat(set.stream()).hasSize(2) .containsExactly("e1", "e2"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -66,7 +66,7 @@ public void two() { public void three() { Set set = Sets.of("e1", "e2", "e3"); assertThat(set).hasSize(3) - .containsExactlyInAnyOrder("e1", "e2", "e3"); + .containsExactly("e1", "e2", "e3"); assertThat(set.stream()).hasSize(3) .containsExactly("e1", "e2", "e3"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -79,7 +79,7 @@ public void three() { public void four() { Set set = Sets.of("e1", "e2", "e3", "e4"); assertThat(set).hasSize(4) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4"); + .containsExactly("e1", "e2", "e3", "e4"); assertThat(set.stream()).hasSize(4) .containsExactly("e1", "e2", "e3", "e4"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -92,7 +92,7 @@ public void four() { public void five() { Set set = Sets.of("e1", "e2", "e3", "e4", "e5"); assertThat(set).hasSize(5) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5"); + .containsExactly("e1", "e2", "e3", "e4", "e5"); assertThat(set.stream()).hasSize(5) .containsExactly("e1", "e2", "e3", "e4", "e5"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -105,7 +105,7 @@ public void five() { public void six() { Set set = Sets.of("e1", "e2", "e3", "e4", "e5", "e6"); assertThat(set).hasSize(6) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5", "e6"); + .containsExactly("e1", "e2", "e3", "e4", "e5", "e6"); assertThat(set.stream()).hasSize(6) .containsExactly("e1", "e2", "e3", "e4", "e5", "e6"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -118,7 +118,7 @@ public void six() { public void seven() { Set set = Sets.of("e1", "e2", "e3", "e4", "e5", "e6", "e7"); assertThat(set).hasSize(7) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5", "e6", "e7"); + .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7"); assertThat(set.stream()).hasSize(7) .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -131,7 +131,7 @@ public void seven() { public void eight() { Set set = Sets.of("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8"); assertThat(set).hasSize(8) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8"); + .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8"); assertThat(set.stream()).hasSize(8) .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -144,7 +144,7 @@ public void eight() { public void nine() { Set set = Sets.of("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9"); assertThat(set).hasSize(9) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9"); + .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9"); assertThat(set.stream()).hasSize(9) .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -157,7 +157,7 @@ public void nine() { public void ten() { Set set = Sets.of("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e10"); assertThat(set).hasSize(10) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e10"); + .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e10"); assertThat(set.stream()).hasSize(10) .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e10"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -174,7 +174,7 @@ public void entries() { Set set = Sets.of(entries); entries[0] = "changed"; assertThat(set).hasSize(11) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e10", "e11"); + .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e10", "e11"); assertThat(set.stream()).hasSize(11) .containsExactly("e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e10", "e11"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -209,7 +209,7 @@ public void copy() { Set set = Sets.copyOf(source); source.set(0, "changed"); assertThat(set).hasSize(2) - .containsExactlyInAnyOrder("e1", "e2"); + .containsExactly("e1", "e2"); assertThat(set.stream()).hasSize(2) .containsExactly("e1", "e2"); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); @@ -230,7 +230,7 @@ public void array() { Set source = Sets.of("e1", "e2", "e3", "e4", "e5"); Object[] array = source.toArray(); assertThat(array).hasSize(5) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5"); + .containsExactly("e1", "e2", "e3", "e4", "e5"); } @Test @@ -240,12 +240,12 @@ public void array_string() { String[] array = source.toArray(target); assertThat(array).isNotSameAs(target) .hasSize(5) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5"); + .containsExactly("e1", "e2", "e3", "e4", "e5"); target = new String[source.size() + 1]; array = source.toArray(target); assertThat(array).isSameAs(target) - .containsExactlyInAnyOrder("e1", "e2", "e3", "e4", "e5", null); + .containsExactly("e1", "e2", "e3", "e4", "e5", null); assertThat(array[target.length - 1]).isNull(); } @@ -295,7 +295,7 @@ public void hash_min_value() { Set set = Sets.of("e1", "polygenelubricants", "GydZG_", "DESIGNING WORKHOUSES", "e5"); - assertThat(set).containsExactlyInAnyOrder("e5", "polygenelubricants", "GydZG_", "DESIGNING WORKHOUSES", "e1"); + assertThat(set).containsExactly("e1", "polygenelubricants", "GydZG_", "DESIGNING WORKHOUSES", "e5"); } @Test @@ -393,4 +393,23 @@ public void iterator_empty() { assertThat(holder.set).isFalse(); } + @Test + public void collector() { + List source = new ArrayList<>(); + source.add("e1"); + source.add("e2"); + source.add("e1"); + Set set = source.stream() + .collect(Sets.toSet()); + source.set(0, "changed"); + assertThat(set).hasSize(2) + .containsExactly("e1", "e2"); + assertThat(set.stream()).hasSize(2) + .containsExactly("e1", "e2"); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.add("a")); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.remove("a")); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.remove("e1")); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> set.clear()); + } + } diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/resource/ResourceImpl.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/resource/ResourceImpl.java index cd076499b4..ad9dc74d69 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/resource/ResourceImpl.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/resource/ResourceImpl.java @@ -1,9 +1,7 @@ package aQute.bnd.osgi.resource; import static aQute.lib.collections.Logic.retain; -import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.groupingBy; -import static java.util.stream.Collectors.toList; import java.io.InputStream; import java.net.URI; @@ -34,7 +32,7 @@ class ResourceImpl implements Resource, Comparable, RepositoryContent void setCapabilities(List capabilities) { allCapabilities = Lists.copyOf(capabilities); capabilityMap = capabilities.stream() - .collect(groupingBy(Capability::getNamespace, collectingAndThen(toList(), Lists::copyOf))); + .collect(groupingBy(Capability::getNamespace, Lists.toList())); locations = null; // clear so equals/hashCode can recompute } @@ -50,7 +48,7 @@ public List getCapabilities(String namespace) { void setRequirements(List requirements) { allRequirements = Lists.copyOf(requirements); requirementMap = requirements.stream() - .collect(groupingBy(Requirement::getNamespace, collectingAndThen(toList(), Lists::copyOf))); + .collect(groupingBy(Requirement::getNamespace, Lists.toList())); } @Override diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java index 0800262c9f..cf8d6d90a3 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java @@ -1,8 +1,6 @@ package aQute.bnd.repository.maven.provider; import static aQute.bnd.osgi.Constants.BSN_SOURCE_SUFFIX; -import static java.util.stream.Collectors.collectingAndThen; -import static java.util.stream.Collectors.toSet; import java.io.Closeable; import java.io.File; @@ -594,7 +592,7 @@ synchronized boolean init() { source = source.replaceAll("(\\s|,|;|\n|\r)+", "\n"); } Set multi = Strings.splitAsStream(configuration.multi()) - .collect(collectingAndThen(toSet(), Sets::copyOf)); + .collect(Sets.toSet()); this.index = new IndexFile(domain, reporter, indexFile, source, storage, client.promiseFactory(), multi); this.index.open();