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

ucar.ma2.Index Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

The newest version!
/*
 * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
 *
 * Portions of this software were developed by the Unidata Program at the
 * University Corporation for Atmospheric Research.
 *
 * Access and use of this software shall impose the following obligations
 * and understandings on the user. The user is granted the right, without
 * any fee or cost, to use, copy, modify, alter, enhance and distribute
 * this software, and any derivative works thereof, and its supporting
 * documentation for any purpose whatsoever, provided that this entire
 * notice appears in all copies of the software, derivative works and
 * supporting documentation.  Further, UCAR requests that the user credit
 * UCAR/Unidata in any publications that result from the use of this
 * software or in any product that includes this software. The names UCAR
 * and/or Unidata, however, may not be used in any advertising or publicity
 * to endorse or promote any products or commercial entity unless specific
 * written permission is obtained from UCAR/Unidata. The user also
 * understands that UCAR/Unidata is not obligated to provide the user with
 * any support, consulting, training or assistance of any kind with regard
 * to the use, operation and performance of this software nor to provide
 * the user with any updates, revisions, new versions or "bug fixes."
 *
 * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
 */
package ucar.ma2;

import java.util.List;

/**
 * Indexes for Multidimensional arrays. An Index refers to a particular element of an array.
 * 

* This is a generalization of index as int[]. Its main function is * to do the index arithmetic to translate an n-dim index into a 1-dim index. * The user obtains this by calling getIndex() on an Array. * The set() and seti() routines are convenience routines for 1-7 dim arrays. * * @author caron * @see Array */ public class Index implements Cloneable { public static final Index0D scalarIndexImmutable = new Index0D(); // immutable, so can be shared /** * Generate a subclass of Index optimized for this array's rank * @param shape use this shape * @return a subclass of Index optimized for this array's rank */ static public Index factory(int[] shape) { int rank = shape.length; switch (rank) { case 0: return new Index0D(); case 1: return new Index1D(shape); case 2: return new Index2D(shape); case 3: return new Index3D(shape); case 4: return new Index4D(shape); case 5: return new Index5D(shape); case 6: return new Index6D(shape); case 7: return new Index7D(shape); default: return new Index(shape); } } private static Index factory(int rank) { switch (rank) { case 0: return new Index0D(); case 1: return new Index1D(); case 2: return new Index2D(); case 3: return new Index3D(); case 4: return new Index4D(); case 5: return new Index5D(); case 6: return new Index6D(); case 7: return new Index7D(); default: return new Index(rank); } } /** * Compute total number of elements in the array. * * @param shape length of array in each dimension. * @return total number of elements in the array. */ static public long computeSize(int[] shape) { long product = 1; for (int ii = shape.length - 1; ii >= 0; ii--) product *= shape[ii]; return product; } /** * Compute standard strides based on array's shape. * * @param shape length of array in each dimension. * @param stride put result here * @return standard strides based on array's shape. */ static private long computeStrides(int[] shape, int[] stride) { long product = 1; for (int ii = shape.length - 1; ii >= 0; ii--) { final int thisDim = shape[ii]; if (thisDim < 0) throw new NegativeArraySizeException(); stride[ii] = (int) product; product *= thisDim; } return product; } //////////////////////////////////////////////////////////////////////////////////////////// protected int[] shape; protected int[] stride; protected int rank; protected long size; // total number of elements protected int offset; // element = offset + stride[0]*current[0] + ... private boolean fastIterator = true; // use fast iterator if in canonical order protected int[] current; // current element's index, used only for the general case /** * General case Index - use when you want to manipulate current elements yourself * @param rank rank of the Index */ protected Index(int rank) { this.rank = rank; shape = new int[rank]; current = new int[rank]; stride = new int[rank]; } /** * Constructor for subclasses only. * @param _shape describes an index section: slowest varying comes first (row major) */ protected Index(int[] _shape) { this.shape = new int[_shape.length]; // optimization over clone System.arraycopy(_shape, 0, this.shape, 0, _shape.length); rank = shape.length; current = new int[rank]; stride = new int[rank]; size = computeStrides(shape, stride); offset = 0; } /** * Constructor that lets you set the strides yourself. * This is used as a counter, not a description of an index section. * @param _shape Index shape * @param _stride Index stride */ public Index(int[] _shape, int[] _stride) { this.shape = new int[_shape.length]; // optimization over clone System.arraycopy(_shape, 0, this.shape, 0, _shape.length); this.stride = new int[_stride.length]; // optimization over clone System.arraycopy(_stride, 0, this.stride, 0, _stride.length); rank = shape.length; current = new int[rank]; size = computeSize(shape); offset = 0; } /** * subclass specialization/optimization calculations */ protected void precalc() { } /** * Create a new Index based on current one, except * flip the index so that it runs from shape[index]-1 to 0. * * @param index dimension to flip * @return new index with flipped dimension */ Index flip(int index) { if ((index < 0) || (index >= rank)) throw new IllegalArgumentException(); Index i = (Index) this.clone(); i.offset += stride[index] * (shape[index] - 1); i.stride[index] = -stride[index]; i.fastIterator = false; i.precalc(); // any subclass-specific optimizations return i; } /** * create a new Index based on a subsection of this one, with rank reduction if * dimension length == 1. * * @param ranges array of Ranges that specify the array subset. * Must be same rank as original Array. * A particular Range: 1) may be a subset; 2) may be null, meaning use entire Range. * @return new Index, with same or smaller rank as original. * @throws InvalidRangeException if ranges dont match current shape */ Index section(List ranges) throws InvalidRangeException { // check ranges are valid if (ranges.size() != rank) throw new InvalidRangeException("Bad ranges [] length"); for (int ii = 0; ii < rank; ii++) { Range r = ranges.get(ii); if (r == null) continue; if ((r.first() < 0) || (r.first() >= shape[ii])) throw new InvalidRangeException("Bad range starting value at index " + ii + " == " + r.first()); if ((r.last() < 0) || (r.last() >= shape[ii])) throw new InvalidRangeException("Bad range ending value at index " + ii + " == " + r.last()); } int reducedRank = rank; for (Range r : ranges) { if ((r != null) && (r.length() == 1)) reducedRank--; } Index newindex = Index.factory(reducedRank); newindex.offset = offset; // calc shape, size, and index transformations // calc strides into original (backing) store int newDim = 0; for (int ii = 0; ii < rank; ii++) { Range r = ranges.get(ii); if (r == null) { // null range means use the whole original dimension newindex.shape[newDim] = shape[ii]; newindex.stride[newDim] = stride[ii]; //if (name != null) newindex.name[newDim] = name[ii]; newDim++; } else if (r.length() != 1) { newindex.shape[newDim] = r.length(); newindex.stride[newDim] = stride[ii] * r.stride(); newindex.offset += stride[ii] * r.first(); //if (name != null) newindex.name[newDim] = name[ii]; newDim++; } else { newindex.offset += stride[ii] * r.first(); // constant due to rank reduction } } newindex.size = computeSize(newindex.shape); newindex.fastIterator = fastIterator && (newindex.size == size); // if equal, then its not a real subset, so can still use fastIterator newindex.precalc(); // any subclass-specific optimizations return newindex; } /** * create a new Index based on a subsection of this one, without rank reduction. * * @param ranges list of Ranges that specify the array subset. * Must be same rank as original Array. * A particular Range: 1) may be a subset; 2) may be null, meaning use entire Range. * @return new Index, with same rank as original. * @throws InvalidRangeException if ranges dont match current shape */ Index sectionNoReduce(List ranges) throws InvalidRangeException { // check ranges are valid if (ranges.size() != rank) throw new InvalidRangeException("Bad ranges [] length"); for (int ii = 0; ii < rank; ii++) { Range r = ranges.get(ii); if (r == null) continue; if ((r.first() < 0) || (r.first() >= shape[ii])) throw new InvalidRangeException("Bad range starting value at index " + ii + " == " + r.first()); if ((r.last() < 0) || (r.last() >= shape[ii])) throw new InvalidRangeException("Bad range ending value at index " + ii + " == " + r.last()); } // allocate Index newindex = Index.factory(rank); newindex.offset = offset; // calc shape, size, and index transformations // calc strides into original (backing) store for (int ii = 0; ii < rank; ii++) { Range r = ranges.get(ii); if (r == null) { // null range means use the whole original dimension newindex.shape[ii] = shape[ii]; newindex.stride[ii] = stride[ii]; } else { newindex.shape[ii] = r.length(); newindex.stride[ii] = stride[ii] * r.stride(); newindex.offset += stride[ii] * r.first(); } //if (name != null) newindex.name[ii] = name[ii]; } newindex.size = computeSize(newindex.shape); newindex.fastIterator = fastIterator && (newindex.size == size); // if equal, then its not a real subset, so can still use fastIterator newindex.precalc(); // any subclass-specific optimizations return newindex; } /** * Create a new Index based on current one by * eliminating any dimensions with length one. * * @return the new Index */ Index reduce() { Index c = this; for (int ii = 0; ii < rank; ii++) if (shape[ii] == 1) { // do this on the first one you find Index newc = c.reduce(ii); return newc.reduce(); // any more to do? } return c; } /** * Create a new Index based on current one by * eliminating the specified dimension; * * @param dim: dimension to eliminate: must be of length one, else IllegalArgumentException * @return the new Index */ Index reduce(int dim) { if ((dim < 0) || (dim >= rank)) throw new IllegalArgumentException("illegal reduce dim " + dim); if (shape[dim] != 1) throw new IllegalArgumentException("illegal reduce dim " + dim + " : length != 1"); Index newindex = Index.factory(rank - 1); newindex.offset = offset; int count = 0; for (int ii = 0; ii < rank; ii++) { if (ii != dim) { newindex.shape[count] = shape[ii]; newindex.stride[count] = stride[ii]; //if (name != null) newindex.name[count] = name[ii]; count++; } } newindex.size = computeSize(newindex.shape); newindex.fastIterator = fastIterator; newindex.precalc(); // any subclass-specific optimizations return newindex; } /** * create a new Index based on current one, except * transpose two of the indices. * * @param index1 transpose these two indices * @param index2 transpose these two indices * @return new Index with transposed indices */ Index transpose(int index1, int index2) { if ((index1 < 0) || (index1 >= rank)) throw new IllegalArgumentException(); if ((index2 < 0) || (index2 >= rank)) throw new IllegalArgumentException(); Index newIndex = (Index) this.clone(); newIndex.stride[index1] = stride[index2]; newIndex.stride[index2] = stride[index1]; newIndex.shape[index1] = shape[index2]; newIndex.shape[index2] = shape[index1]; /* if (name != null) { newIndex.name[index1] = name[index2]; newIndex.name[index2] = name[index1]; } */ newIndex.fastIterator = false; newIndex.precalc(); // any subclass-specific optimizations return newIndex; } /** * create a new Index based on a permutation of the current indices * * @param dims: the old index dim[k] becomes the new kth index. * @return new Index with permuted indices */ Index permute(int[] dims) { if (dims.length != shape.length) throw new IllegalArgumentException(); for (int dim : dims) if ((dim < 0) || (dim >= rank)) throw new IllegalArgumentException(); boolean isPermuted = false; Index newIndex = (Index) this.clone(); for (int i = 0; i < dims.length; i++) { newIndex.stride[i] = stride[dims[i]]; newIndex.shape[i] = shape[dims[i]]; //if (name != null) newIndex.name[i] = name[dims[i]]; if (i != dims[i]) isPermuted = true; } newIndex.fastIterator = fastIterator && !isPermuted; // useful optimization newIndex.precalc(); // any subclass-specific optimizations return newIndex; } /** * Get the number of dimensions in the array. * @return the number of dimensions in the array. */ public int getRank() { return rank; } /** * Get the shape: length of array in each dimension. * @return the shape */ public int[] getShape() { int[] result = new int[shape.length]; // optimization over clone System.arraycopy(shape, 0, result, 0, shape.length); return result; } /** * Get the length of the ith dimension. * @return the ith dimension length * @param index which dimension. must be in [0, getRank()) */ public int getShape(int index) { return shape[index]; } /** * Get an index iterator for traversing the array in canonical order. * @param maa the array to iterate through * @return an index iterator for traversing the array in canonical order. * @see IndexIterator */ IndexIterator getIndexIterator(Array maa) { if (fastIterator) return new IteratorFast(size, maa); else return new IteratorImpl(maa); } IteratorFast getIndexIteratorFast(Array maa) { return new IteratorFast(size, maa); } boolean isFastIterator() { return fastIterator; } /** * Get the total number of elements in the array. * @return the total number of elements in the array. */ public long getSize() { return size; } /** * Get the current element's index into the 1D backing array. * @return the current element's index into the 1D backing array. */ public int currentElement() { int value = offset; // NB: dont have to check each index again for (int ii = 0; ii < rank; ii++) // general rank value += current[ii] * stride[ii]; return value; } /** * Get the current counter. * @return copy of the current counter. */ public int[] getCurrentCounter() { return current.clone(); } // only use from FastIterator, where the indices are not permuted /** * Set the current counter from the 1D "current element" * currElement = offset + stride[0]*current[0] + ... * @param currElement set to this value */ public void setCurrentCounter(int currElement) { currElement -= offset; for (int ii = 0; ii < rank; ii++) { // general rank current[ii] = currElement / stride[ii]; currElement -= current[ii] * stride[ii]; } set(current); // transfer to subclass fields } /** * Increment the current element by 1. Used by IndexIterator. * General rank, with subclass specialization. * * @return currentElement() */ public int incr() { int digit = rank - 1; while (digit >= 0) { current[digit]++; if (current[digit] < shape[digit]) break; // normal exit current[digit] = 0; // else, carry digit--; } return currentElement(); } /** * Set the current element's index. General-rank case. * * @param index set current value to these values * @return this, so you can use A.get(i.set(i)) * @throws ArrayIndexOutOfBoundsException if index.length != rank. */ public Index set(int[] index) { if (index.length != rank) throw new ArrayIndexOutOfBoundsException(); System.arraycopy(index, 0, current, 0, rank); return this; } /** * set current element at dimension dim to v * @param dim set this dimension * @param value to this value */ public void setDim(int dim, int value) { if (value < 0 || value >= shape[dim]) // check index here throw new ArrayIndexOutOfBoundsException(); current[dim] = value; } /** * set current element at dimension 0 to v * * @param v set 0th dimension index to this value * @return this, so you can use A.get(i.set(i)) */ public Index set0(int v) { setDim(0, v); return this; } /** * set current element at dimension 1 to v * * @param v set dimension 1 index to this value * @return this, so you can use A.get(i.set(i)) */ public Index set1(int v) { setDim(1, v); return this; } /** * set current element at dimension 2 to v * * @param v set dimension 2 index to this value * @return this, so you can use A.get(i.set(i)) */ public Index set2(int v) { setDim(2, v); return this; } /** * set current element at dimension 3 to v * * @param v set dimension 3 index to this value * @return this, so you can use A.get(i.set(i)) */ public Index set3(int v) { setDim(3, v); return this; } /** * set current element at dimension 4 to v * * @param v set dimension 4 index to this value * @return this, so you can use A.get(i.set(i)) */ public Index set4(int v) { setDim(4, v); return this; } /** * set current element at dimension 5 to v * * @param v set dimension 5 index to this value * @return this, so you can use A.get(i.set(i)) */ public Index set5(int v) { setDim(5, v); return this; } /** * set current element at dimension 6 to v * * @param v set dimension 6 index to this value * @return this, so you can use A.get(i.set(i)) */ public Index set6(int v) { setDim(6, v); return this; } /** * set current element at dimension 0 to v0 * * @param v0 set dimension 0 index to this value * @return this, so you can use A.get(i.set(i)) */ public Index set(int v0) { setDim(0, v0); return this; } /** * set current element at dimension 0,1 to v0,v1 * * @param v0 set dimension 0 index to this value * @param v1 set dimension 1 index to this value * @return this, so you can use A.get(i.set(i,j)) */ public Index set(int v0, int v1) { setDim(0, v0); setDim(1, v1); return this; } /** * set current element at dimension 0,1,2 to v0,v1,v2 * * @param v0 set dimension 0 index to this value * @param v1 set dimension 1 index to this value * @param v2 set dimension 2 index to this value * @return this, so you can use A.get(i.set(i,j,k)) */ public Index set(int v0, int v1, int v2) { setDim(0, v0); setDim(1, v1); setDim(2, v2); return this; } /** * set current element at dimension 0,1,2,3 to v0,v1,v2,v3 * * @param v0 set dimension 0 index to this value * @param v1 set dimension 1 index to this value * @param v2 set dimension 2 index to this value * @param v3 set dimension 3 index to this value * @return this, so you can use A.get(i.set(i,j,k,l)) */ public Index set(int v0, int v1, int v2, int v3) { setDim(0, v0); setDim(1, v1); setDim(2, v2); setDim(3, v3); return this; } /** * set current element at dimension 0,1,2,3,4 to v0,v1,v2,v3,v4 * * @param v0 set dimension 0 index to this value * @param v1 set dimension 1 index to this value * @param v2 set dimension 2 index to this value * @param v3 set dimension 3 index to this value * @param v4 set dimension 4 index to this value * @return this, so you can use A.get(i.set(i,j,k,l,m)) */ public Index set(int v0, int v1, int v2, int v3, int v4) { setDim(0, v0); setDim(1, v1); setDim(2, v2); setDim(3, v3); setDim(4, v4); return this; } /** * set current element at dimension 0,1,2,3,4,5 to v0,v1,v2,v3,v4,v5 * * @param v0 set dimension 0 index to this value * @param v1 set dimension 1 index to this value * @param v2 set dimension 2 index to this value * @param v3 set dimension 3 index to this value * @param v4 set dimension 4 index to this value * @param v5 set dimension 5 index to this value * @return this, so you can use A.get(i.set(i,j,k,l,m,n)) */ public Index set(int v0, int v1, int v2, int v3, int v4, int v5) { setDim(0, v0); setDim(1, v1); setDim(2, v2); setDim(3, v3); setDim(4, v4); setDim(5, v5); return this; } /** * set current element at dimension 0,1,2,3,4,5,6 to v0,v1,v2,v3,v4,v5,v6 * * @param v0 set dimension 0 index to this value * @param v1 set dimension 1 index to this value * @param v2 set dimension 2 index to this value * @param v3 set dimension 3 index to this value * @param v4 set dimension 4 index to this value * @param v5 set dimension 5 index to this value * @param v6 set dimension 6 index to this value * @return this, so you can use A.get(i.set(i,j,k,l,m,n,p)) */ public Index set(int v0, int v1, int v2, int v3, int v4, int v5, int v6) { setDim(0, v0); setDim(1, v1); setDim(2, v2); setDim(3, v3); setDim(4, v4); setDim(5, v5); setDim(6, v6); return this; } /** * String representation * @return String representation */ public String toStringDebug() { StringBuilder sbuff = new StringBuilder(100); sbuff.setLength(0); sbuff.append(" shape= "); for (int ii = 0; ii < rank; ii++) { sbuff.append(shape[ii]); sbuff.append(" "); } sbuff.append(" stride= "); for (int ii = 0; ii < rank; ii++) { sbuff.append(stride[ii]); sbuff.append(" "); } /* if (name != null) { sbuff.append(" names= "); for (int ii = 0; ii < rank; ii++) { sbuff.append(name[ii]); sbuff.append(" "); } } */ sbuff.append(" offset= ").append(offset); sbuff.append(" rank= ").append(rank); sbuff.append(" size= ").append(size); sbuff.append(" current= "); for (int ii = 0; ii < rank; ii++) { sbuff.append(current[ii]); sbuff.append(" "); } return sbuff.toString(); } public String toString() { StringBuilder sbuff = new StringBuilder(100); sbuff.setLength(0); for (int ii = 0; ii < rank; ii++) { if (ii > 0) sbuff.append(","); sbuff.append(current[ii]); } return sbuff.toString(); } public Object clone() { Index i; try { i = (Index) super.clone(); } catch (CloneNotSupportedException e) { return null; } i.stride = stride.clone(); i.shape = shape.clone(); i.current = new int[rank]; // want zeros // if (name != null) i.name = name.clone(); return i; } ////////////////////////////////////////////////////////////// /* * Set the name of one of the indices. * * @param dim which index? * @param indexName name of index * public void setIndexName(int dim, String indexName) { if (name == null) name = new String[rank]; name[dim] = indexName; } /* * Get the name of one of the indices. * * @param dim which index? * @return name of index, or null if none. * public String getIndexName(int dim) { if (name == null) return null; return name[dim]; } */ private class IteratorImpl implements IndexIterator { private int count = 0; private int currElement = 0; private Index counter; private Array maa; private IteratorImpl(Array maa) { this.maa = maa; counter = (Index) Index.this.clone(); // could be subtype of Index if (rank > 0) counter.current[rank - 1] = -1; // avoid "if first" on every incr. counter.precalc(); //System.out.println("IteratorSlow"); } public boolean hasNext() { return count < size; } public String toString() { return counter.toString(); } public int[] getCurrentCounter() { return counter.getCurrentCounter(); } public Object next() { count++; currElement = counter.incr(); return maa.getObject(currElement); } public double getDoubleCurrent() { return maa.getDouble(currElement); } public double getDoubleNext() { count++; currElement = counter.incr(); return maa.getDouble(currElement); } public void setDoubleCurrent(double val) { maa.setDouble(currElement, val); } public void setDoubleNext(double val) { count++; currElement = counter.incr(); maa.setDouble(currElement, val); } public float getFloatCurrent() { return maa.getFloat(currElement); } public float getFloatNext() { count++; currElement = counter.incr(); return maa.getFloat(currElement); } public void setFloatCurrent(float val) { maa.setFloat(currElement, val); } public void setFloatNext(float val) { count++; currElement = counter.incr(); maa.setFloat(currElement, val); } public long getLongCurrent() { return maa.getLong(currElement); } public long getLongNext() { count++; currElement = counter.incr(); return maa.getLong(currElement); } public void setLongCurrent(long val) { maa.setLong(currElement, val); } public void setLongNext(long val) { count++; currElement = counter.incr(); maa.setLong(currElement, val); } public int getIntCurrent() { return maa.getInt(currElement); } public int getIntNext() { count++; currElement = counter.incr(); return maa.getInt(currElement); } public void setIntCurrent(int val) { maa.setInt(currElement, val); } public void setIntNext(int val) { count++; currElement = counter.incr(); maa.setInt(currElement, val); } public short getShortCurrent() { return maa.getShort(currElement); } public short getShortNext() { count++; currElement = counter.incr(); return maa.getShort(currElement); } public void setShortCurrent(short val) { maa.setShort(currElement, val); } public void setShortNext(short val) { count++; currElement = counter.incr(); maa.setShort(currElement, val); } public byte getByteCurrent() { return maa.getByte(currElement); } public byte getByteNext() { count++; currElement = counter.incr(); return maa.getByte(currElement); } public void setByteCurrent(byte val) { maa.setByte(currElement, val); } public void setByteNext(byte val) { count++; currElement = counter.incr(); maa.setByte(currElement, val); } public char getCharCurrent() { return maa.getChar(currElement); } public char getCharNext() { count++; currElement = counter.incr(); return maa.getChar(currElement); } public void setCharCurrent(char val) { maa.setChar(currElement, val); } public void setCharNext(char val) { count++; currElement = counter.incr(); maa.setChar(currElement, val); } public boolean getBooleanCurrent() { return maa.getBoolean(currElement); } public boolean getBooleanNext() { count++; currElement = counter.incr(); return maa.getBoolean(currElement); } public void setBooleanCurrent(boolean val) { maa.setBoolean(currElement, val); } public void setBooleanNext(boolean val) { count++; currElement = counter.incr(); maa.setBoolean(currElement, val); } public Object getObjectCurrent() { return maa.getObject(currElement); } public Object getObjectNext() { count++; currElement = counter.incr(); return maa.getObject(currElement); } public void setObjectCurrent(Object val) { maa.setObject(currElement, val); } public void setObjectNext(Object val) { count++; currElement = counter.incr(); maa.setObject(currElement, val); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy