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

com.amazon.ion.IonSequence Maven / Gradle / Ivy

There is a newer version: 1.11.9
Show newest version
/*
 * Copyright 2007-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * or in the "license" file accompanying this file. This file 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.amazon.ion;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;



/**
 * Common functionality of Ion list and sexp types.
 * 

* WARNING: This interface should not be implemented or extended by * code outside of this library. *

* Ion sequences implement the standard Java {@link List} interface, behaving * generally as expected, with the following exceptions: *

    *
  • * Due to the reference-equality-based semantics of Ion sequences, methods * like {@link #remove(Object)} do not use {@link Object#equals} as * specified by the contract of {@link java.util.Collection}. * Instead they use reference equality ({@code ==} operator) to find the * given instance. *
  • *
  • * Any given {@link IonValue} instance may be a child of at most one * {@link IonContainer}. Instances may be children of any number of * non-Ion {@link Collection}s. *
  • *
  • * The implementations of {@link List#equals(Object)}} and * {@link List#hashCode()} does not conform to the specification of those * methods in order to conform with Ion's definition of equality which * takes into account the {@link IonSequence}'s {@link IonType} and its * annotations in addition to the contents of the collection. *
      *
    • * {@link List#equals(Object)} always returns false * for any non-{@link IonSequence} implementation of {@link List}, * including the sub-list returned from * {@link IonSequence#subList(int, int)}. *
    • *
    • * {@link List#hashCode()} returns a different hash code than * other {@link List#hashCode()} implementations. including the * sub-list returned from {@link IonSequence#subList(int, int)}. *
    • *
    *
  • *
*/ public interface IonSequence extends IonContainer, List { /** * Returns the element at the specified position in this sequence. * * @param index identifies the element to return. * @return the element at the given index; not null. * @throws NullValueException if {@link #isNullValue()}. * @throws IndexOutOfBoundsException if the index is out of range * (index < 0 || index >= size()). */ public IonValue get(int index) throws NullValueException, IndexOutOfBoundsException; /** * Appends a child value to the end of this sequence. * If {@link #isNullValue()}, then it becomes a single-element * sequence. * * @param child is the value to be appended to this sequence. * @return {@code true} (as per the general contract of the * {@link Collection#add} method). * * @throws NullPointerException * if {@code child} is null. * @throws ContainedValueException * if {@code child} is already part of a container. * @throws IllegalArgumentException * if {@code child} is an {@link IonDatagram}. */ public boolean add(IonValue child) throws ContainedValueException, NullPointerException; /** * Provides a factory that when invoked constructs a new value and * {@code add}s it to this sequence. *

* These two lines are equivalent: *

     *    seq.add().newInt(3);
     *    seq.add(seq.getSystem().newInt(3));
     *
*/ public ValueFactory add(); /** * Inserts a child value at the specified position in this sequence. * If {@link #isNullValue()}, then it becomes a single-element * sequence. * * @param child is the element to be appended to this sequence. * * @throws NullPointerException * if {@code child} is null. * @throws ContainedValueException * if {@code child} is already part of a container. * @throws IllegalArgumentException * if {@code child} is an {@link IonDatagram}. * @throws IndexOutOfBoundsException if the index is out of range * (index < 0 || index > size()). */ public void add(int index, IonValue child) throws ContainedValueException, NullPointerException; /** * Provides a factory that when invoked constructs a new value and * {@code add}s it to this sequence at the specified position. *

* These two lines are equivalent: *

     *    seq.add(12).newInt(3);
     *    seq.add(12, seq.getSystem().newInt(3));
     *
*

* The given {@code index} is validated when the factory's creation method * is invoked, not when this method is invoked. */ public ValueFactory add(int index); /** * Replaces the element at the specified position in this list with the * specified element. * * @param index index of the element to replace. * @param element element to be stored at the specified position. * @return the element previously at the specified index. * * @throws UnsupportedOperationException * if this is an {@link IonDatagram}. * @throws NullPointerException * if the specified element is {@code null}. * @throws ContainedValueException * if the specified element is already part of a container. * @throws IllegalArgumentException * if the specified element is an {@link IonDatagram}. * @throws ReadOnlyValueException * if this value or the specified element {@link #isReadOnly()}. * @throws IndexOutOfBoundsException * if the index is out of range ({@code index < 0 || index >= size()}). */ public IonValue set(int index, IonValue element); /** * Removes the element at the specified position. * Shifts any subsequent elements to the left (subtracts one from their * indices). Returns the element that was removed from the list. * * @param index the index of the element to be removed. * * @return the element previously at the specified position. * * @throws IndexOutOfBoundsException if the index is out of range * (index < 0 || index >= size()). */ public IonValue remove(int index); /** * Removes a given {@link IonValue} from this sequence, if it is present. *

* Due to the reference-equality-based semantics of Ion sequences, * this method does not use {@link Object#equals} as specified by the * contract of {@link java.util.Collection}. Instead it uses reference * equality ({@code ==} operator) to find the given instance. * * @return {@code true} if this sequence changed as a result of the call. * * @throws NullPointerException if {@code o} is {@code null}. * @throws ClassCastException if {@code o} is not an {@link IonValue}. */ public boolean remove(Object o); /** * Removes all elements from this sequence that are also contained in the * specified collection. After this call returns, this sequence will * contain no elements in common with the specified collection. *

* Due to the reference-equality-based semantics of Ion sequences, * this method does not use {@link Object#equals} as specified by the * contract of {@link java.util.Collection}. Instead it uses reference * equality ({@code ==} operator) to find the given instance. * * @return {@code true} if this sequence changed as a result of the call. * * @throws NullPointerException if {@code c} is {@code null}. * @throws NullPointerException if {@code c} contains one or more * {@code null} elements. * @throws ClassCastException if {@code c} contains one or more elements * that do not implement {@link IonValue}. */ public boolean removeAll(Collection c); /** * Retains only the elements in this sequence that are also contained in * the specified collection. In other words, removes from this sequence * all of its elements that are not contained in the specified collection. *

* Due to the reference-equality-based semantics of Ion sequences, * this method does not use {@link Object#equals} as specified by the * contract of {@link java.util.Collection}. Instead it uses reference * equality ({@code ==} operator) to find the given instance. * * @return {@code true} if this sequence changed as a result of the call. * * @throws NullPointerException if {@code c} is {@code null}. * @throws NullPointerException if {@code c} contains one or more * {@code null} elements. * @throws ClassCastException if {@code c} contains one or more elements * that do not implement {@link IonValue}. */ public boolean retainAll(Collection c); /** * Determines whether this sequence contains the given instance. *

* Due to the reference-equality-based semantics of Ion sequences, * this method does not use {@link Object#equals} as specified by the * contract of {@link java.util.Collection}. Instead it uses reference * equality ({@code ==} operator) to find the given instance. * * @return {@code true} if {@code o} is an element of this sequence. * * @throws NullPointerException if {@code o} is {@code null}. * @throws ClassCastException if {@code o} is not an {@link IonValue}. */ public boolean contains(Object o); /** * Determines whether this sequence contains all of the given instances. *

* Due to the reference-equality-based semantics of Ion sequences, * this method does not use {@link Object#equals} as specified by the * contract of {@link java.util.Collection}. Instead it uses reference * equality ({@code ==} operator) to find the given instances. * * @return {@code true} if this sequence contains all of the elements of * the given collection. * * @throws NullPointerException if {@code c} is {@code null}. * @throws NullPointerException if {@code c} contains one or more * {@code null} elements. * @throws ClassCastException if {@code c} contains one or more elements * that do not implement {@link IonValue}. */ public boolean containsAll(Collection c); /** * Returns the index in the sequence of the specified element, * or -1 if this sequence doesn't contain the element. *

* Due to the reference-equality-based semantics of Ion sequences, * this method does not use {@link Object#equals} as specified by the * contract of {@link java.util.List}. Instead it uses reference * equality ({@code ==} operator) to find the instance. * * @param o the element to search for. * @return the index in this sequence of the element, * or -1 if this sequence doesn't contain the element. */ public int indexOf(Object o); /** * Returns the index in the sequence of the specified element, * or -1 if this sequence doesn't contain the element. *

* * Due to the reference-equality-based semantics of Ion sequences, * this method does not use {@link Object#equals} as specified by the * contract of {@link java.util.List}. Instead it uses reference * equality ({@code ==} operator) to find the instance. * * And since IonSequences do not allow for duplicates this method behaves * in the same way as {@link IonSequence#indexOf(Object)} * * * @param o the element to search for. * @return the index in this sequence of the element, * or -1 if this sequence doesn't contain the element. */ public int lastIndexOf(Object o); /** * Appends all of the elements in the specified collection to the end of * this sequence, in the order that they are returned by the collection's * iterator. * The behavior of this operation is unspecified if the specified * collection is modified while the operation is in progress. * (Note that this will occur if the specified collection is this sequence, * and it's nonempty.) *

* Since Ion values can only have a single parent, this method will fail if * the given collection is a non-empty {@link IonContainer}. * * @param c * elements to be appended to this sequence. * * @return {@code true} if this sequence changed as a result of the call. * * @throws UnsupportedOperationException * if this is an {@link IonDatagram}. * @throws ClassCastException * if one of the elements of the collection is not an {@link IonValue} * @throws NullPointerException * if one of the elements of the collection is {@code null}. * @throws ContainedValueException * if one of the elements is already contained by an {@link IonContainer}. */ public boolean addAll(Collection c); /** * Inserts all of the elements in the specified collection into this * sequence at the specified position. Shifts the element currently at that * position (if any) and any subsequent elements to the right (increases * their indices). The new elements will appear in this sequence in the * order that they are returned by the specified collection's iterator. * The behavior of this operation is unspecified if the specified * collection is modified while the operation is in progress. * (Note that this will occur if the specified collection is this sequence, * and it's nonempty.) *

* Since Ion values can only have a single parent, this method will fail if * the given collection is a non-empty {@link IonContainer}. * * @param index * index at which to insert first element from the specified collection. * @param c * elements to be inserted into this sequence. * * @return {@code true} if this sequence changed as a result of the call. * * @throws UnsupportedOperationException * if this is an {@link IonDatagram}. * @throws ClassCastException * if one of the elements of the collection is not an {@link IonValue} * @throws NullPointerException * if one of the elements of the collection is {@code null}. * @throws ContainedValueException * if one of the elements is already contained by an {@link IonContainer}. * @throws IndexOutOfBoundsException * if the index is out of range (index < 0 || index > size()). */ public boolean addAll(int index, Collection c); /** * Returns a list iterator of the elements in this sequence (in proper * order). *

* The result does not support {@link ListIterator#add(Object)} or * {@link ListIterator#set(Object)}. * If this sequence {@link #isReadOnly()} then it also does not support * {@link Iterator#remove()}. */ public ListIterator listIterator(); /** * Returns a list iterator of the elements in this sequence (in proper * order), starting at the specified position in this sequence. *

* The result does not support {@link ListIterator#add(Object)} or * {@link ListIterator#set(Object)}. * If this sequence {@link #isReadOnly()} then it also does not support * {@link Iterator#remove()}. * * @param index * index of first element to be returned from the list iterator (by a call * to the {@code next} method). * * @throws IndexOutOfBoundsException * if the index is out of range ({@code index < 0 || index > size()}). */ public ListIterator listIterator(int index); /** *

* Returns a view of the portion of this list according to * {@link List#subList(int, int)} contract. *

* *

* Sublist methods will throw a * {@link java.util.ConcurrentModificationException} if its parent list, * i.e. this list, had any changes that affect its size the after sublist * was created. *

* * The implementation of {@link List} returned by this method * implements {@link List#equals(Object)} and * {@link List#equals(Object)} ()} per the specification of these methods. * However, the existing implementation of {@link IonSequence} does not * provide a specification compliant {@link List#equals} and * {@link List#hashCode()}} which results to the following caveats: * * Given: * * * int[] ints = new int[] {1, 2, 3, 4}; * IonList list = SYSTEM.newList(ints); * IonSexp sexp = SYSTEM.newSexp(ints) * IonSexp dgrm = SYSTEM.newDatagram(ints) * List listSubList = list.subList(0, ints.size()) * List sexpSubList = sexp.subList(0, ints.size()) * List dgrmSubList = sexp.subList(0, ints.size()) * List arrayList = new ArrayList(); * for(int i : ints) { arrayList.add(SYSTEM.newInt(i)); } * * * {@link IonSequence#equals(Object)} always returns false when presented * with a non {@link IonSequence} instance of {@link List}. * Hence, the following invocations of {@link Object#equals(Object)} * return false even if the contained elements are equivalent. This * means that {@link Object#equals(Object)} is not symmetric in these * cases. The reason for the asymmetry is historical: * {@link IonSequence} has long violated the contract outlined by the * {@link List} documentation. For the current major version of this * library we maintain backwards compatibility and support this behaviour * as-is. * * * list.equals(listSubList) // false * list.equals(sexpSubList) // false * list.equals(dgrm) // false * list.equals(arrayList) // false * * sexp.equals(listSubList) // false * sexp.equals(sexpSubList) // false * sexp.equals(dgrm) // false * sexp.equals(arrayList) // false * * dgrm.equals(listSubList) // false * dgrm.equals(sexpSubList) // false * dgrm.equals(dgrmSubList) // false * dgrm.equals(arrayList) // false * * * However, {@link IonSequence#subList(int, int)} was implemented much * later and faithfully implements {@link List#equals(Object)} meaning * the cases below all work as expected. While {@link IonSequence} * does not comply with the specification for {@link List#equals(Object)} * because it has to comply with Ion's rules for equality, the same is * not true for sub-lists. Unlike {@link IonSequence}, sub-lists have * no notion of an {@link IonType}, annotations or nullability which * allows for compliance with the {@link List} specification. * * * listSubList.equals(listSubList); // true * listSubList.equals(sexpSubList); // true * listSubList.equals(dgrmSubList); // true * listSubList.equals(list); // true * listSubList.equals(sexp); // true * listSubList.equals(arrayList); // true * * sexpSubList.equals(listSubList); // true * sexpSubList.equals(sexpSubList); // true * sexpSubList.equals(dgrmSubList); // true * sexpSubList.equals(list); // true * sexpSubList.equals(sexp); // true * sexpSubList.equals(arrayList); // true * * dgrmSubList.equals(listSubList); // true * dgrmSubList.equals(sexpSubList); // true * dgrmSubList.equals(dgrmSubList); // true * dgrmSubList.equals(list); // true * dgrmSubList.equals(sexp); // true * dgrmSubList.equals(arrayList); // true * * * @see List#subList(int, int) */ public List subList(int fromIndex, int toIndex); /** * Returns an array containing all of the elements in this sequence in * proper order. Obeys the general contract of the * {@link Collection#toArray()} method. *

* If this sequence is an {@linkplain #isNullValue() Ion null value}, it * will behave like an empty sequence. * * @return an array containing all of the elements in this sequence in * proper order. */ public IonValue[] toArray(); /** * Returns an array containing all of the elements in this sequence in * proper order; the runtime type of the returned array is that of the * specified array. Obeys the general contract of the * {@link Collection#toArray()} method. *

* If this sequence is an {@linkplain #isNullValue() Ion null value}, it * will behave like an empty sequence. * * @param a the array into which the elements of this sequence are to be * stored, if it is big enough; otherwise, a new array of the same * runtime type is allocated for this purpose. * * @return an array containing all of the elements in this sequence in * proper order. * * @throws ArrayStoreException if the runtime type of the specified array * is not a supertype of the runtime type of every element in this * sequence. * @throws NullPointerException if the specified array is null. */ public T[] toArray(T[] a); /** * Removes all children of this sequence, returning them in an array. * This is much more efficient than iterating the sequence and removing * children one by one. * * @return a new array with all of the children of {@code s} in order, or * {@code null} if {@link #isNullValue()}. * * @throws NullPointerException if {@code type} is {@code null}. * @throws ClassCastException if any value in this sequence does not * implement the given type. */ public T[] extract(Class type); public IonSequence clone() throws UnknownSymbolException; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy