From 0b44b62ccf878eca0c16db720b808df4ebd55306 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 30 May 2018 12:31:24 +0200 Subject: [PATCH] Improve SingletonSet.spliterator() We can use a Iterator-less version of the spliterator, adding further characteristics. Expose these spliterators via SingletonSpliterators utility class. Change-Id: I3d7e19cc303c2f0c9c9d79d173bb78d8d5b77eac Signed-off-by: Robert Varga --- .../yangtools/util/SingletonSet.java | 14 ++ .../yangtools/util/SingletonSpliterators.java | 136 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 common/util/src/main/java/org/opendaylight/yangtools/util/SingletonSpliterators.java diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/SingletonSet.java b/common/util/src/main/java/org/opendaylight/yangtools/util/SingletonSet.java index 76359e2f7c..091ae4c1db 100644 --- a/common/util/src/main/java/org/opendaylight/yangtools/util/SingletonSet.java +++ b/common/util/src/main/java/org/opendaylight/yangtools/util/SingletonSet.java @@ -15,6 +15,7 @@ import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import java.util.Set; +import java.util.Spliterator; import javax.annotation.Nonnull; import org.opendaylight.yangtools.concepts.Immutable; @@ -46,6 +47,11 @@ public abstract class SingletonSet implements Set, Immutable, Serializable return null; } + @Override + public Spliterator spliterator() { + return SingletonSpliterators.immutableOfNull(); + } + @Override public String toString() { return "[null]"; @@ -81,6 +87,9 @@ public abstract class SingletonSet implements Set, Immutable, Serializable return Iterators.singletonIterator(getElement()); } + @Override + public abstract Spliterator spliterator(); + @Nonnull @Override public final Object[] toArray() { @@ -201,5 +210,10 @@ public abstract class SingletonSet implements Set, Immutable, Serializable public String toString() { return "[" + element + ']'; } + + @Override + public Spliterator spliterator() { + return SingletonSpliterators.immutableOf(element); + } } } diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/SingletonSpliterators.java b/common/util/src/main/java/org/opendaylight/yangtools/util/SingletonSpliterators.java new file mode 100644 index 0000000000..d67626c574 --- /dev/null +++ b/common/util/src/main/java/org/opendaylight/yangtools/util/SingletonSpliterators.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.util; + +import static java.util.Objects.requireNonNull; + +import com.google.common.annotations.Beta; +import java.util.Spliterator; +import java.util.function.Consumer; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yangtools.concepts.Mutable; + +/** + * Utility methods for instantiating {@link Spliterator}s containing a single element. + * + * @author Robert Varga + */ +@Beta +@NonNullByDefault +public final class SingletonSpliterators { + private SingletonSpliterators() { + + } + + /** + * Create a new {@link Spliterator} reporting specified element. It has the following characteristics: + *
    + *
  • {@link Spliterator#DISTINCT}
  • + *
  • {@link Spliterator#IMMUTABLE}
  • + *
  • {@link Spliterator#NONNULL}
  • + *
  • {@link Spliterator#ORDERED}
  • + *
  • {@link Spliterator#SIZED}
  • + *
  • {@link Spliterator#SUBSIZED}
  • + *
+ * + * @param element Single element to report + * @param the type of elements returned by this Spliterator + * @return A new spliterator + * @throws NullPointerException if element is null + */ + public static Spliterator immutableOf(final T element) { + return new ImmutableNonNull<>(element); + } + + /** + * Create a new {@link Spliterator} reporting a {@code null} element. It has the following characteristics: + *
    + *
  • {@link Spliterator#DISTINCT}
  • + *
  • {@link Spliterator#IMMUTABLE}
  • + *
  • {@link Spliterator#ORDERED}
  • + *
  • {@link Spliterator#SIZED}
  • + *
  • {@link Spliterator#SUBSIZED}
  • + *
+ * + * @return A new spliterator + */ + public static <@Nullable T> Spliterator immutableOfNull() { + return new ImmutableNull<>(); + } + + private static final class ImmutableNonNull implements Mutable, Spliterator { + private final T element; + + private boolean consumed; + + private ImmutableNonNull(final T element) { + this.element = requireNonNull(element); + } + + @Override + public boolean tryAdvance(final @Nullable Consumer action) { + requireNonNull(action); + if (consumed) { + return false; + } + + action.accept(element); + consumed = true; + return true; + } + + @Override + public @Nullable Spliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return consumed ? 0 : 1; + } + + @Override + public int characteristics() { + return Spliterator.NONNULL | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE + | Spliterator.DISTINCT | Spliterator.ORDERED; + } + } + + private static final class ImmutableNull<@Nullable E> implements Mutable, Spliterator { + private boolean consumed; + + @Override + public boolean tryAdvance(final @Nullable Consumer action) { + requireNonNull(action); + if (consumed) { + return false; + } + + action.accept(null); + consumed = true; + return true; + } + + @Override + public @Nullable Spliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return consumed ? 0 : 1; + } + + @Override + public int characteristics() { + return Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE | Spliterator.DISTINCT + | Spliterator.ORDERED; + } + } +} -- 2.36.6