/*
 * Copyright (C) 2007 The Guava Authors
 *
 * 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 org.glassfish.jersey.internal.guava;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Objects;

import static org.glassfish.jersey.internal.guava.Preconditions.checkElementIndex;
import static org.glassfish.jersey.internal.guava.Preconditions.checkNotNull;
import static org.glassfish.jersey.internal.guava.Preconditions.checkPositionIndex;
import static org.glassfish.jersey.internal.guava.Preconditions.checkPositionIndexes;
import static org.glassfish.jersey.internal.guava.Preconditions.checkState;

Static utility methods pertaining to List instances. Also see this class's counterparts Sets, Maps and Queues.

See the Guava User Guide article on Lists.

Author:Kevin Bourrillion, Mike Bostock, Louis Wasserman
Since:2.0 (imported from Google Collections Library)
/** * Static utility methods pertaining to {@link List} instances. Also see this * class's counterparts {@link Sets}, {@link Maps} and {@link Queues}. * <p> * <p>See the Guava User Guide article on <a href= * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Lists"> * {@code Lists}</a>. * * @author Kevin Bourrillion * @author Mike Bostock * @author Louis Wasserman * @since 2.0 (imported from Google Collections Library) */
public final class Lists { private Lists() { } // ArrayList
Creates a mutable, empty ArrayList instance (for Java 6 and earlier).

Note: if mutability is not required, use of.of() instead.

Note for Java 7 and later: this method is now unnecessary and should be treated as deprecated. Instead, use the ArrayList constructor directly, taking advantage of the new "diamond" syntax.

/** * Creates a <i>mutable</i>, empty {@code ArrayList} instance (for Java 6 and * earlier). * <p> * <p><b>Note:</b> if mutability is not required, use {@link * ImmutableList#of()} instead. * <p> * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and * should be treated as deprecated. Instead, use the {@code ArrayList} * {@linkplain ArrayList#ArrayList() constructor} directly, taking advantage * of the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>. */
private static <E> ArrayList<E> newArrayList() { return new ArrayList<E>(); }
Creates a mutable ArrayList instance containing the given elements; a very thin shortcut for creating an empty list then calling Iterables.addAll.

Note: if mutability is not required and the elements are non-null, use copyOf.copyOf(Iterable) instead. (Or, change elements to be a FluentIterable and call elements.toList().)

Note for Java 7 and later: if elements is a Collection, you don't need this method. Use the ArrayList constructor directly, taking advantage of the new "diamond" syntax.

/** * Creates a <i>mutable</i> {@code ArrayList} instance containing the given * elements; a very thin shortcut for creating an empty list then calling * {@link Iterables#addAll}. * <p> * <p><b>Note:</b> if mutability is not required and the elements are * non-null, use {@link ImmutableList#copyOf(Iterable)} instead. (Or, change * {@code elements} to be a {@link FluentIterable} and call * {@code elements.toList()}.) * <p> * <p><b>Note for Java 7 and later:</b> if {@code elements} is a {@link * Collection}, you don't need this method. Use the {@code ArrayList} * {@linkplain ArrayList#ArrayList(Collection) constructor} directly, taking * advantage of the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>. */
public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) { checkNotNull(elements); // for GWT // Let ArrayList's sizing logic work, if possible return (elements instanceof Collection) ? new ArrayList<E>(Collections2.cast(elements)) : newArrayList(elements.iterator()); }
Creates a mutable ArrayList instance containing the given elements; a very thin shortcut for creating an empty list and then calling Iterators.addAll.

Note: if mutability is not required and the elements are non-null, use copyOf.copyOf(Iterator) instead.

/** * Creates a <i>mutable</i> {@code ArrayList} instance containing the given * elements; a very thin shortcut for creating an empty list and then calling * {@link Iterators#addAll}. * <p> * <p><b>Note:</b> if mutability is not required and the elements are * non-null, use {@link ImmutableList#copyOf(Iterator)} instead. */
public static <E> ArrayList<E> newArrayList(Iterator<? extends E> elements) { ArrayList<E> list = newArrayList(); Iterators.addAll(list, elements); return list; }
Returns a reversed view of the specified list. For example, Lists.reverse(Arrays.asList(1, 2, 3)) returns a list containing 3, 2, 1. The returned list is backed by this list, so changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

The returned list is random-access if the specified list is random access.

Since:7.0
/** * Returns a reversed view of the specified list. For example, {@code * Lists.reverse(Arrays.asList(1, 2, 3))} returns a list containing {@code 3, * 2, 1}. The returned list is backed by this list, so changes in the returned * list are reflected in this list, and vice-versa. The returned list supports * all of the optional list operations supported by this list. * <p> * <p>The returned list is random-access if the specified list is random * access. * * @since 7.0 */
private static <T> List<T> reverse(List<T> list) { if (list instanceof ReverseList) { return ((ReverseList<T>) list).getForwardList(); } else { return new ReverseList<T>(list); } }
An implementation of List.equals(Object).
/** * An implementation of {@link List#equals(Object)}. */
static boolean equalsImpl(List<?> list, Object object) { if (object == checkNotNull(list)) { return true; } if (!(object instanceof List)) { return false; } List<?> o = (List<?>) object; return list.size() == o.size() && Iterators.elementsEqual(list.iterator(), o.iterator()); }
An implementation of List.indexOf(Object).
/** * An implementation of {@link List#indexOf(Object)}. */
static int indexOfImpl(List<?> list, Object element) { ListIterator<?> listIterator = list.listIterator(); while (listIterator.hasNext()) { if (Objects.equals(element, listIterator.next())) { return listIterator.previousIndex(); } } return -1; }
An implementation of List.lastIndexOf(Object).
/** * An implementation of {@link List#lastIndexOf(Object)}. */
static int lastIndexOfImpl(List<?> list, Object element) { ListIterator<?> listIterator = list.listIterator(list.size()); while (listIterator.hasPrevious()) { if (Objects.equals(element, listIterator.previous())) { return listIterator.nextIndex(); } } return -1; } private static class ReverseList<T> extends AbstractList<T> { private final List<T> forwardList; ReverseList(List<T> forwardList) { this.forwardList = checkNotNull(forwardList); } List<T> getForwardList() { return forwardList; } private int reverseIndex(int index) { int size = size(); checkElementIndex(index, size); return (size - 1) - index; } private int reversePosition(int index) { int size = size(); checkPositionIndex(index, size); return size - index; } @Override public void add(int index, T element) { forwardList.add(reversePosition(index), element); } @Override public void clear() { forwardList.clear(); } @Override public T remove(int index) { return forwardList.remove(reverseIndex(index)); } @Override protected void removeRange(int fromIndex, int toIndex) { subList(fromIndex, toIndex).clear(); } @Override public T set(int index, T element) { return forwardList.set(reverseIndex(index), element); } @Override public T get(int index) { return forwardList.get(reverseIndex(index)); } @Override public int size() { return forwardList.size(); } @Override public List<T> subList(int fromIndex, int toIndex) { checkPositionIndexes(fromIndex, toIndex, size()); return reverse(forwardList.subList( reversePosition(toIndex), reversePosition(fromIndex))); } @Override public Iterator<T> iterator() { return listIterator(); } @Override public ListIterator<T> listIterator(int index) { int start = reversePosition(index); final ListIterator<T> forwardIterator = forwardList.listIterator(start); return new ListIterator<T>() { boolean canRemoveOrSet; @Override public void add(T e) { forwardIterator.add(e); forwardIterator.previous(); canRemoveOrSet = false; } @Override public boolean hasNext() { return forwardIterator.hasPrevious(); } @Override public boolean hasPrevious() { return forwardIterator.hasNext(); } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } canRemoveOrSet = true; return forwardIterator.previous(); } @Override public int nextIndex() { return reversePosition(forwardIterator.nextIndex()); } @Override public T previous() { if (!hasPrevious()) { throw new NoSuchElementException(); } canRemoveOrSet = true; return forwardIterator.next(); } @Override public int previousIndex() { return nextIndex() - 1; } @Override public void remove() { CollectPreconditions.checkRemove(canRemoveOrSet); forwardIterator.remove(); canRemoveOrSet = false; } @Override public void set(T e) { checkState(canRemoveOrSet); forwardIterator.set(e); } }; } } }