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

org.yamcs.utils.IntArray Maven / Gradle / Ivy

There is a newer version: 5.10.9
Show newest version
package org.yamcs.utils;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.PrimitiveIterator;
import java.util.stream.IntStream;

/**
 * expandable array of ints
 * 
 */
public class IntArray implements Iterable {
    public static final int DEFAULT_CAPACITY = 10;
    private int[] a;
    private int length;

    // caches the hashCode
    private int hash;

    /**
     * Creates a sorted int array with a default initial capacity
     */
    public IntArray() {
        a = new int[DEFAULT_CAPACITY];
    }

    /**
     * Creates an IntArray with a given initial capacity
     * 
     * @param capacity
     */
    public IntArray(int capacity) {
        a = new int[capacity];
    }

    private IntArray(int[] a1) {
        a = a1;
        length = a1.length;
    }

    /**
     * Creates the IntArray with the backing array
     * 
     * @param array
     * @return a new object containing all the values from the passed array
     */
    public static IntArray wrap(int... array) {
        return new IntArray(array);
    }

    /**
     * add value to the array
     * 
     * @param x
     *            * - value to be added
     */
    public void add(int x) {
        hash = 0;
        ensureCapacity(length + 1);
        a[length] = x;
        length++;
    }

    public void add(int pos, int x) {
        if (pos > length) {
            throw new IndexOutOfBoundsException("Index: " + pos + " length: " + length);
        }
        hash = 0;
        ensureCapacity(length + 1);
        System.arraycopy(a, pos, a, pos + 1, length - pos);
        a[pos] = x;
        length++;
    }

    /**
     * get element at position
     * 
     * @param pos
     * @return the element at the specified position
     */
    public int get(int pos) {
        rangeCheck(pos);

        return a[pos];
    }

    /**
     * Remove element at position shifting all subsequent elements to the left
     * 
     * @param pos
     * @return the element removed
     */
    public int remove(int pos) {
        rangeCheck(pos);
        hash = 0;
        int r = a[pos];

        System.arraycopy(a, pos + 1, a, pos, length - pos - 1);
        length--;
        return r;

    }

    private void ensureCapacity(int minCapacity) {
        if (minCapacity <= a.length) {
            return;
        }

        int capacity = a.length;
        int newCapacity = capacity + (capacity >> 1);
        if (newCapacity < minCapacity) {
            newCapacity = minCapacity;
        }

        a = Arrays.copyOf(a, newCapacity);
    }

    public IntStream stream() {
        return Arrays.stream(a, 0, length);
    }

    public boolean isEmpty() {
        return a.length == 0;
    }

    public int[] toArray() {
        return Arrays.copyOf(a, length);
    }

    /**
     * @return the size of the array (which is smaller or equal than the length of the underlying int[] array)
     */
    public int size() {
        return length;
    }

    public void set(int pos, int x) {
        rangeCheck(pos);
        hash = 0;
        a[pos] = x;
    }

    private void rangeCheck(int pos) {
        if (pos >= length) {
            throw new IndexOutOfBoundsException("Index: " + pos + " length: " + length);
        }
    }

    /**
     * Returns the index of the first occurrence of the specified element in the array, or -1 if the array does not
     * contain the element.
     * 
     * @param x
     *            element which is searched for
     * 
     * @return the index of the first occurrence of the specified element in this list, or -1 if this list does not
     *         contain the element.
     */
    public int indexOf(int x) {
        for (int i = 0; i < length; i++) {
            if (a[i] == x)
                return i;
        }
        return -1;
    }

    /**
     * get the backing array
     * 
     * @return the backing array
     */
    public int[] array() {
        return a;
    }

    /**
     * Assuming that the array is sorted, performs a binary search and returns the position of the found element.
     * 
     * See {@link Arrays#binarySearch(int[], int)} for details.
     * 
     * If the array is not sorted, the behaviour is undefined.
     * 
     * @param x
     *            - the value to be searched for
     * @return
     */
    public int binarySearch(int x) {
        return Arrays.binarySearch(a, 0, length, x);
    }

    /**
     * return the number of elements of the intersection of the two arrays
     * 

* both this and input have to be sorted */ public int intersectionSize(IntArray input) { int count = 0; int idx1 = 0; int idx2 = 0; while (idx1 < this.length && idx2 < input.length) { if (this.a[idx1] < input.a[idx2]) { idx1++; } else if (this.a[idx1] > input.a[idx2]) { idx2++; } else { count++; idx1++; idx2++; } } return count; } /** * Assuming that a1 and a2 are sorted, returns a new array storing the union. *

* sizeHint is the expected size of the returned array */ public static IntArray union(IntArray a1, IntArray a2, int sizeHint) { IntArray union = new IntArray(sizeHint); int idx1 = 0; int idx2 = 0; while (idx1 < a1.length && idx2 < a2.length) { if (a1.a[idx1] < a2.a[idx2]) { union.add(a1.a[idx1]); idx1++; } else if (a1.a[idx1] > a2.a[idx2]) { union.add(a2.a[idx2]); idx2++; } else { union.add(a1.a[idx1]); idx1++; idx2++; } } while (idx1 < a1.length) { union.add(a1.a[idx1]); idx1++; } while (idx2 < a2.length) { union.add(a2.a[idx2]); idx2++; } return union; } public void sort() { Arrays.sort(a, 0, length); hash = 0; } /** * Sort the array concurrently swapping the elements in the list such that the correspondence is kept. * * The list has to contain the same number of elements as the array * * @param list */ public void sort(List list) { if (list.size() != length) { throw new IllegalArgumentException("The list has not the same number of elements as the array"); } if (length == 0) { return; } quickSort(0, length - 1, list); } private void quickSort(int lo, int hi, List list) { int pi = partition(lo, hi, list); if (lo < pi - 1) { quickSort(lo, pi - 1, list); } if (pi < hi) { quickSort(pi, hi, list); } } private int partition(int lo, int hi, List list) { int pivot = a[(lo + hi) >>> 1]; int i = lo, j = hi; while (i <= j) { while (a[i] < pivot) i++; while (a[j] > pivot) j--; if (i <= j) { swap(i, j, list); i++; j--; } } return i; } private void swap(int i, int j, List list) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; Collections.swap(list, i, j); hash = 0; } @Override public int hashCode() { int h = hash; if (h == 0 && length > 0) { h = 1; for (int i = 0; i < length; i++) { h = 31 * h + a[i]; } hash = h; } return h; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; IntArray other = (IntArray) obj; if (length != other.length) return false; for (int i = 0; i < length; i++) { if (a[i] != other.a[i]) return false; } return true; } public String toString() { StringBuilder b = new StringBuilder(); int n = length - 1; if (n == -1) { return "[]"; } b.append('['); for (int i = 0;; i++) { b.append(a[i]); if (i == n) return b.append(']').toString(); b.append(", "); } } /** * Compares two arrays. Assuming that the arrays a1 and a2 are sorted, it returns *

    *
  • 0 if a1 == a2
  • *
  • 1 if a1 is a subset of a2
  • *
  • 2 if a2 is a subset of a1
  • *
  • -1 otherwise
  • *
* * If the arrays are not sorted the return is meaningless. * * @param a1 * - first array * @param a2 * - second array */ public static int compare(IntArray a1, IntArray a2) { int i1 = 0; int i2 = 0; int c = 0; while (i1 < a1.size() && i2 < a2.size()) { int x1 = a1.get(i1); int x2 = a2.get(i2); if (x1 == x2) { i1++; i2++; continue; } if (x1 > x2) { if (c == 0) { c = 1; } else if (c == 2) { c = -1; break; } i2++; } else { // x1 < x2 if (c == 0) { c = 2; } else if (c == 1) { c = -1; break; } i1++; } } if (c != -1) { if (i1 < a1.size()) { c = (c == 0) ? 2 : -1; } else if (i2 < a2.size()) { c = (c == 0) ? 1 : -1; } } return c; } @Override public Iterator iterator() { return new IntArrayIterator(); } private class IntArrayIterator implements PrimitiveIterator.OfInt { private int idx = 0; @Override public boolean hasNext() { return idx < length; } @Override public int nextInt() { if (!hasNext()) { throw new NoSuchElementException(); } return a[idx++]; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy