All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.epam.deltix.util.collections.IndexedArrayList Maven / Gradle / Ivy
/*
* Copyright 2021 EPAM Systems, Inc
*
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership. 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.epam.deltix.util.collections;
import java.util.*;
import com.epam.deltix.util.collections.generated.*;
import java.io.Serializable;
/**
* A special implementation of List which provides very fast indexOf and
* contains operations.
* Notes:
*
* Duplicate elements are not allowed. Therefore, indexOf ()
* and lastIndexOf () always return identical results.
* Insertion into the middle is not allowed.
*
*/
public class IndexedArrayList implements List , Serializable {
static final long serialVersionUID = 1L;
private ObjectToIntegerHashMap mElemToIdxMap;
private List mElemList;
private int mFirstNullIdx = -1;
private boolean mAllowAddingDuplicates = false;
public void setAllowAddingDuplicates (boolean ignoreDuplicates) {
mAllowAddingDuplicates = ignoreDuplicates;
}
public static IndexedArrayList wrapIfNecessary (List in) {
if (in == null)
return (null);
if (in instanceof IndexedArrayList)
return ((IndexedArrayList ) in);
return (new IndexedArrayList (in));
}
public IndexedArrayList () {
this (32);
}
public IndexedArrayList (int capacity) {
mElemToIdxMap = new ObjectToIntegerHashMap (capacity);
mElemList = new ObjectArrayList (capacity);
}
public IndexedArrayList (int capacity, boolean ignoreDuplicates) {
this (capacity);
setAllowAddingDuplicates(ignoreDuplicates);
}
public IndexedArrayList (List list) {
int num = list.size ();
mElemList = list;
mElemToIdxMap = new ObjectToIntegerHashMap (num);
for (int ii = 0; ii < num; ii++)
map (list.get (ii), ii);
}
public IndexedArrayList (Collection list) {
this (new ObjectArrayList (list));
}
public IndexedArrayList (E [] array) {
int num = array.length;
mElemList = new ArrayList (num);
mElemToIdxMap = new ObjectToIntegerHashMap (num);
for (int ii = 0; ii < num; ii++) {
E e = array [ii];
mElemList.add (e);
map (e, ii);
}
}
private void map (E e, int idx) {
if (e == null) {
if (mFirstNullIdx < 0 || idx < mFirstNullIdx)
mFirstNullIdx = idx;
}
else if (!mElemToIdxMap.put (e, idx))
throw new IllegalArgumentException (
"Duplicate element: " + e + " at index " + idx
);
}
private void unmap (E e, int idx) {
if (e == null) {
assert mFirstNullIdx >= 0 && idx >= mFirstNullIdx :
"idx: " + idx + "; mFirstNullIdx: " + mFirstNullIdx;
if (idx == mFirstNullIdx) {
int size = mElemList.size ();
for (;;) {
mFirstNullIdx++;
if (mFirstNullIdx == size) {
mFirstNullIdx = -1;
break;
}
if (mElemList.get (mFirstNullIdx) == null)
break;
}
}
}
else {
int prevIdx = mElemToIdxMap.remove (e, -1);
assert prevIdx == idx : "prevIdx: " + prevIdx + "; idx: " + idx;
}
}
public boolean remove (Object o) {
int idx = indexOf (o);
if (idx < 0)
return (false);
remove (idx);
return (true);
}
public boolean contains (Object o) {
if (o == null)
return (mFirstNullIdx >= 0);
return (mElemToIdxMap.containsKey (o));
}
public int indexOf (Object o) {
if (o == null)
return (mFirstNullIdx);
return (mElemToIdxMap.get (o, -1));
}
public int lastIndexOf (Object o) {
if (o == null || mAllowAddingDuplicates)
return (mElemList.lastIndexOf (o));
return (mElemToIdxMap.get (o, -1));
}
public E remove (int index) {
E e = mElemList.remove (index);
unmap (e, index);
final int s = size ();
for (int ii = index; ii < s; ii++) {
E ee = mElemList.get (ii);
if (ee != null)
mElemToIdxMap.put (ee, ii);
}
return (e);
}
public ListIterator listIterator (int index) {
return (mElemList.listIterator ());
}
public E get (int index) {
return (mElemList.get (index));
}
public T [] toArray (T [] a) {
return (mElemList.toArray (a));
}
public boolean addAll (Collection extends E> c) {
for (E e : c)
add (e);
return (!c.isEmpty ());
}
public E set (int index, E element) {
if (element != null) {
int existIdx = mElemToIdxMap.get (element, -1);
// Still call set () to ensure correct identities
if (existIdx == index)
return (mElemList.set (index, element));
if (existIdx >= 0)
throw new IllegalArgumentException (
"Element " + element + " being set at index " + index +
" already exists at index " + existIdx
);
}
E prev = mElemList.set (index, element);
unmap (prev, index);
map (element, index);
return (prev);
}
public void add (int index, E element) {
if (index != size ())
throw new UnsupportedOperationException ("Insertion is not supported");
add (element);
}
public boolean addAll (int index, Collection extends E> c) {
if (index != size ())
throw new UnsupportedOperationException ("Insertion is not supported");
return (addAll (c));
}
public boolean retainAll (Collection> c) {
throw new UnsupportedOperationException ("Removal is not supported");
}
public boolean removeAll (Collection> c) {
throw new UnsupportedOperationException ("Removal is not supported");
}
public boolean containsAll (Collection > c) {
for (Object e : c)
if (!mElemToIdxMap.containsKey (e))
return (false);
return (true);
}
public Object [] toArray () {
return (mElemList.toArray ());
}
public List subList (int fromIndex, int toIndex) {
return (mElemList.subList (fromIndex, toIndex));
}
public int size () {
return (mElemList.size ());
}
public boolean add (E o) {
if (o != null) {
int existIdx = mElemToIdxMap.get (o, -1);
if (existIdx >= 0) {
if (mAllowAddingDuplicates)
return (false);
throw new IllegalArgumentException (
"Element " + o +
" already exists at index " + existIdx
);
}
map (o, mElemList.size ());
}
mElemList.add (o);
return (true);
}
public int getIndexOrAdd (E o) {
int idx;
if (o == null) {
idx = mFirstNullIdx;
if (idx < 0) {
idx = mElemList.size ();
mElemList.add (o);
}
}
else {
idx = mElemToIdxMap.get (o, -1);
if (idx < 0) {
idx = mElemList.size ();
mElemList.add (o);
map (o, idx);
}
}
return (idx);
}
public void clear () {
mElemList.clear ();
mElemToIdxMap.clear ();
}
public boolean isEmpty () {
return (mElemList.isEmpty ());
}
public Iterator iterator () {
return (mElemList.iterator ());
}
public ListIterator listIterator () {
return (mElemList.listIterator ());
}
}