All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hivemq.client.internal.util.collections.ImmutableList Maven / Gradle / Ivy

Go to download

HiveMQ MQTT Client is an MQTT 5.0 and MQTT 3.1.1 compatible and feature-rich high-performance Java client library with different API flavours and backpressure support

The newest version!
/*
 * Copyright 2018-present HiveMQ and the HiveMQ Community
 *
 * 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 com.hivemq.client.internal.util.collections;

import com.hivemq.client.annotations.Immutable;
import com.hivemq.client.internal.util.Checks;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

/**
 * @author Silvio Giebl
 */
@Immutable
public interface ImmutableList<@NotNull E> extends List, RandomAccess {

    static  @NotNull ImmutableList of() {
        return ImmutableEmptyList.of();
    }

    @Contract("null -> fail")
    static  @NotNull ImmutableList of(final @Nullable E e) {
        return ImmutableElement.of(e);
    }

    @Contract("null, _ -> fail; _, null -> fail")
    static  @NotNull ImmutableList of(final @Nullable E e1, final @Nullable E e2) {
        return ImmutableArray.of(e1, e2);
    }

    @Contract("null, _, _ -> fail; _, null, _ -> fail; _, _, null -> fail")
    static  @NotNull ImmutableList of(final @Nullable E e1, final @Nullable E e2, final @Nullable E e3) {
        return ImmutableArray.of(e1, e2, e3);
    }

    @SafeVarargs
    @Contract("null, _, _, _ -> fail; _, null, _, _ -> fail; _, _, null, _ -> fail; _, _, _, null -> fail")
    static  @NotNull ImmutableList of(
            final @Nullable E e1, final @Nullable E e2, final @Nullable E e3, final @Nullable E @Nullable ... others) {

        Checks.notNull(others, "Immutable list elements");
        final Object[] array = new Object[3 + others.length];
        array[0] = e1;
        array[1] = e2;
        array[2] = e3;
        System.arraycopy(others, 0, array, 3, others.length);
        return ImmutableArray.of(array);
    }

    @Contract("null -> fail")
    static  @NotNull ImmutableList copyOf(final @Nullable E @Nullable [] elements) {
        return copyOf(elements, "Immutable list");
    }

    @Contract("null, _ -> fail")
    static  @NotNull ImmutableList copyOf(final @Nullable E @Nullable [] elements, final @NotNull String name) {
        Checks.notNull(elements, name);
        switch (elements.length) {
            case 0:
                return ImmutableEmptyList.of();
            case 1:
                return ImmutableElement.of(elements[0], name);
            default:
                return ImmutableArray.of(Arrays.copyOf(elements, elements.length, Object[].class), name);
        }
    }

    @Contract("null -> fail")
    static  @NotNull ImmutableList copyOf(final @Nullable Collection<@Nullable ? extends E> elements) {
        return copyOf(elements, "Immutable list");
    }

    @Contract("null, _ -> fail")
    static  @NotNull ImmutableList copyOf(
            final @Nullable Collection<@Nullable ? extends E> elements, final @NotNull String name) {

        Checks.notNull(elements, name);
        if (elements instanceof ImmutableList) {
            //noinspection unchecked
            return ((ImmutableList) elements).trim();
        }
        switch (elements.size()) {
            case 0:
                return ImmutableEmptyList.of();
            case 1:
                return ImmutableElement.of(Builder.first(elements), name);
            default:
                return ImmutableArray.of(elements.toArray(), name);
        }
    }

    static  @NotNull Builder builder() {
        return new Builder<>();
    }

    static  @NotNull Builder builder(final int capacity) {
        return new Builder<>(capacity);
    }

    @Override
    default boolean isEmpty() {
        return size() == 0;
    }

    @Override
    @NotNull E get(int index);

    @Override
    default boolean contains(final @Nullable Object o) {
        return indexOf(o) >= 0;
    }

    @Override
    default boolean containsAll(final @NotNull Collection<@Nullable ?> c) {
        Checks.notNull(c, "Collection");
        for (final Object o : c) {
            if (!contains(o)) {
                return false;
            }
        }
        return true;
    }

    @Override
    default @NotNull ImmutableListIterator iterator() {
        return listIterator();
    }

    @Override
    default @NotNull ImmutableListIterator listIterator() {
        return listIterator(0);
    }

    @Override
    @NotNull ImmutableListIterator listIterator(int index);

    @Override
    @NotNull ImmutableList subList(int fromIndex, int toIndex);

    default @NotNull ImmutableList trim() {
        return this;
    }

    @Override
    @Deprecated
    default boolean add(final @Nullable E e) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default boolean remove(final @Nullable Object o) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default boolean addAll(final @NotNull Collection c) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default boolean removeAll(final @NotNull Collection c) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default boolean retainAll(final @NotNull Collection c) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default boolean removeIf(final @NotNull Predicate filter) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default void clear() {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default void add(final int index, final @Nullable E element) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default @Nullable E remove(final int index) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default @Nullable E set(final int index, final @Nullable E element) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default boolean addAll(final int index, final @NotNull Collection c) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default void replaceAll(final @NotNull UnaryOperator operator) {
        throw new UnsupportedOperationException();
    }

    @Override
    @Deprecated
    default void sort(final @Nullable Comparator c) {
        throw new UnsupportedOperationException();
    }

    interface ImmutableListIterator extends ListIterator {

        @Override
        @Deprecated
        default void remove() {
            throw new UnsupportedOperationException();
        }

        @Override
        @Deprecated
        default void set(final @Nullable E e) {
            throw new UnsupportedOperationException();
        }

        @Override
        @Deprecated
        default void add(final @Nullable E e) {
            throw new UnsupportedOperationException();
        }
    }

    class Builder {

        private static final int INITIAL_CAPACITY = 4;

        private @Nullable E e;
        private @NotNull Object @Nullable [] array;
        private int size;

        private Builder() {}

        private Builder(final int capacity) {
            if (capacity > 1) {
                array = new Object[capacity];
            }
        }

        private int newCapacity(final int capacity) {
            return capacity + (capacity >> 1);
        }

        private @NotNull Object @NotNull [] ensureCapacity(final int capacity) {
            assert capacity > 1;
            if (array == null) {
                array = new Object[Math.max(INITIAL_CAPACITY, capacity)];
            } else if (capacity > array.length) {
                array = Arrays.copyOf(array, Math.max(newCapacity(array.length), capacity), Object[].class);
            }
            if (this.e != null) {
                array[0] = this.e;
                this.e = null;
            }
            return array;
        }

        public void ensureFree(final int free) {
            final int newCapacity = size + free;
            if (newCapacity > 1) {
                ensureCapacity(newCapacity);
            }
        }

        public @NotNull Builder add(final @NotNull E e) {
            Checks.notNull(e, "Immutable list element");
            if (size == 0) {
                this.e = e;
                size = 1;
            } else {
                final int newSize = size + 1;
                ensureCapacity(newSize)[size] = e;
                size = newSize;
            }
            return this;
        }

        public @NotNull Builder addAll(final @NotNull Collection<@NotNull ? extends E> elements) {
            Checks.notNull(elements, "Immutable list elements");
            final int elementsSize = elements.size();
            switch (elementsSize) {
                case 0:
                    break;
                case 1:
                    add(first(elements));
                    break;
                default:
                    final int newSize = size + elementsSize;
                    final Object[] array = ensureCapacity(newSize);
                    if ((elements instanceof List) && (elements instanceof RandomAccess)) {
                        //noinspection unchecked
                        final List list = (List) elements;
                        for (int i = 0; i < elementsSize; i++) {
                            array[size + i] = Checks.notNull(list.get(i), "Immutable list");
                        }
                    } else {
                        int i = size;
                        for (final E e : elements) {
                            array[i++] = Checks.notNull(e, "Immutable list");
                        }
                    }
                    size = newSize;
            }
            return this;
        }

        public int getSize() {
            return size;
        }

        public @NotNull ImmutableList build() {
            switch (size) {
                case 0:
                    return ImmutableEmptyList.of();
                case 1:
                    assert e != null;
                    return new ImmutableElement<>(e);
                default:
                    assert array != null;
                    if (array.length == size) {
                        return new ImmutableArray<>(array);
                    }
                    return new ImmutableArray<>(Arrays.copyOfRange(array, 0, size, Object[].class));
            }
        }

        static  @NotNull E first(final @NotNull Collection<@NotNull E> elements) {
            return (elements instanceof List) ? ((List) elements).get(0) : elements.iterator().next();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy