/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.stetho.common;
import java.util.AbstractList;
import java.util.Collections;
import java.util.List;
import java.util.RandomAccess;
public final class ListUtil {
private ListUtil() {
}
/**
* Compares the contents of two {@link List}s by using object identity.
*/
public static <T> boolean identityEquals(List<? extends T> list1, List<? extends T> list2) {
if (list1 == list2) {
return true;
}
int size = list1.size();
if (size != list2.size()) {
return false;
}
for (int i = 0; i < size; ++i) {
if (list1.get(i) != list2.get(i)) {
return false;
}
}
return true;
}
/**
* Copies the given {@link List} and returns the copy as an immutable {@link List}.
*/
public static <T> List<T> copyToImmutableList(List<T> list) {
if (list instanceof ImmutableList) {
return list;
}
int size = list.size();
switch (size) {
case 0:
return Collections.emptyList();
case 1:
return new OneItemImmutableList<>(list.get(0));
case 2:
return new TwoItemImmutableList<>(list.get(0), list.get(1));
case 3:
return new ThreeItemImmutableList<>(list.get(0), list.get(1), list.get(2));
case 4:
return new FourItemImmutableList<>(list.get(0), list.get(1), list.get(2), list.get(3));
case 5:
return new FiveItemImmutableList<>(
list.get(0), list.get(1), list.get(2), list.get(3), list.get(4));
default:
Object[] array = list.toArray();
return new ImmutableArrayList<>(array);
}
}
public static <T> List<T> newImmutableList(T item) {
return new OneItemImmutableList<>(item);
}
public static <T> List<T> newImmutableList(T itemOne, T itemTwo) {
return new TwoItemImmutableList<>(itemOne, itemTwo);
}
private static interface ImmutableList<E> extends List<E>, RandomAccess {
}
private static final class ImmutableArrayList<E>
extends AbstractList<E> implements ImmutableList<E> {
private final Object[] mArray;
public ImmutableArrayList(Object[] array) {
mArray = array;
}
@Override
@SuppressWarnings("unchecked")
public E get(int location) {
return (E) mArray[location];
}
@Override
public int size() {
return mArray.length;
}
}
private static final class OneItemImmutableList<E>
extends AbstractList<E> implements ImmutableList<E> {
private final E mItem;
public OneItemImmutableList(E item) {
mItem = item;
}
@Override
public E get(int location) {
if (location == 0) {
return mItem;
} else {
throw new IndexOutOfBoundsException();
}
}
@Override
public int size() {
return 1;
}
}
private static final class TwoItemImmutableList<E>
extends AbstractList<E> implements ImmutableList<E> {
private final E mItem0;
private final E mItem1;
public TwoItemImmutableList(E item0, E item1) {
mItem0 = item0;
mItem1 = item1;
}
@Override
public E get(int location) {
switch (location) {
case 0:
return mItem0;
case 1:
return mItem1;
default:
throw new IndexOutOfBoundsException();
}
}
@Override
public int size() {
return 2;
}
}
private static final class ThreeItemImmutableList<E>
extends AbstractList<E> implements ImmutableList<E> {
private final E mItem0;
private final E mItem1;
private final E mItem2;
public ThreeItemImmutableList(E item0, E item1, E item2) {
mItem0 = item0;
mItem1 = item1;
mItem2 = item2;
}
@Override
public E get(int location) {
switch (location) {
case 0:
return mItem0;
case 1:
return mItem1;
case 2:
return mItem2;
default:
throw new IndexOutOfBoundsException();
}
}
@Override
public int size() {
return 3;
}
}
private static final class FourItemImmutableList<E>
extends AbstractList<E> implements ImmutableList<E> {
private final E mItem0;
private final E mItem1;
private final E mItem2;
private final E mItem3;
public FourItemImmutableList(E item0, E item1, E item2, E item3) {
mItem0 = item0;
mItem1 = item1;
mItem2 = item2;
mItem3 = item3;
}
@Override
public E get(int location) {
switch (location) {
case 0:
return mItem0;
case 1:
return mItem1;
case 2:
return mItem2;
case 3:
return mItem3;
default:
throw new IndexOutOfBoundsException();
}
}
@Override
public int size() {
return 4;
}
}
private static final class FiveItemImmutableList<E>
extends AbstractList<E> implements ImmutableList<E> {
private final E mItem0;
private final E mItem1;
private final E mItem2;
private final E mItem3;
private final E mItem4;
public FiveItemImmutableList(E item0, E item1, E item2, E item3, E item4) {
mItem0 = item0;
mItem1 = item1;
mItem2 = item2;
mItem3 = item3;
mItem4 = item4;
}
@Override
public E get(int location) {
switch (location) {
case 0:
return mItem0;
case 1:
return mItem1;
case 2:
return mItem2;
case 3:
return mItem3;
case 4:
return mItem4;
default:
throw new IndexOutOfBoundsException();
}
}
@Override
public int size() {
return 5;
}
}
}