Java tutorial
<@pp.dropOutputFile/><#list types as T><@pp.changeOutputFile name=T.displayName+"ArrayList.java"/> /** * Copyright 2010 The Apache Software Foundation * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.hadoop.hbase.regionserver.idx.support.arrays; import org.apache.hadoop.hbase.util.Bytes; import java.util.Arrays; import java.util.Iterator; import java.util.NoSuchElementException; import org.apache.commons.lang.ArrayUtils;<#if T.clazz=="BigDecimal"> import java.math.BigDecimal;</#if><#if(T.kind=="integerArray"||T.kind=="comparable")> import org.apache.hadoop.hbase.util.ClassSize;</#if> /** * A list designed to be used as the key store for indexed HBase. * <p/> * NOTE: This class is completely unsynchronised. */ public class $ { T.displayName}ArrayList implements List<${T.clazz}>{ <#if T.kind=="integerArray"><#assign arrayPrimitive = T.primitive?substring(0,T.primitive?index_of('['))> </#if> //DO NOT EDIT THIS FILE, EDIT THE FMPP TEMPLATE INSTEAD. //To generate source execute // **/src/contib/indexed# ant -f build-fmpp.xml -lib lib/fmpp-0.19.14 /** * Default initial size of the array backing this list. */ private static final int DEFAULT_SIZE = 1; /** * The scaling factor we use to resize the backing buffer when the list needs to grow. */ private static final float SCALE_FACTOR = 1.5f; /** * The array backing this list. */ private ${T.primitive}[]values; /** * The number of values present in the list. */ private int size; <#if(T.kind=="integerArray")> /** * The accumulated heap size of elements stored in this list. */ private long totalElementsHeapSize;</#if> /** * Constructor that initialises with the default size. */ public ${T.displayName}ArrayList() { this(DEFAULT_SIZE); } /** * Constructor which initialises with the specified initial capacity. * * @param initialCapacity the initial capacity of the backing array */ public ${T.displayName}ArrayList(int initialCapacity) { <#if T.kind == "integerArray"> values = new ${arrayPrimitive}[initialCapacity][]; <#else> values = new ${T.primitive}[initialCapacity]; </#if> } /** * Constructor which initialises the content from the supplied array list. * * @param initial the initial contents */ public ${T.displayName}ArrayList(${T.displayName}ArrayList initial) { // Initialise the internal storage to the appropriate size this(initial.size); // Copy over the references/values System.arraycopy(initial.values, 0, this.values, 0, initial.size); this.size = initial.size; } /** * Adds the element to the end of the list. * * @param element the new element */ public void add(${T.primitive}element) { ensureCapacity(size + 1); values[size] = element; size++; <#if (T.kind == "integerArray")> totalElementsHeapSize += ClassSize.ARRAY + (element != null ? element.length * Bytes.SIZEOF_${arrayPrimitive?upper_case}: 0); </#if> } <#if T.clazz!="byte[]"> @Override public void add(byte[] bytes) { add(fromBytes(bytes)); }</#if> <#if T.kind=="comparable"> @Override public int compare(${T.clazz}needle, int compareToIndex) { ${T.clazz} compareTo = values[compareToIndex]; return needle.compareTo(compareTo); }<#elseif T.kind=="floatingPoint"> @Override public int compare(${T.clazz}needle, int compareToIndex) { ${T.primitive} compareTo = values[compareToIndex]; return ${T.clazz}.compare(needle, compareTo); }<#elseif T.kind=="integer"> @Override public int compare(${T.clazz}needle, int compareToIndex) { ${T.primitive} compareTo = values[compareToIndex]; if (needle > compareTo) { return 1; } else if (needle < compareTo) { return -1; } else { return 0; } }<#elseif T.kind=="integerArray"> @Override public int compare(${T.clazz}needle, int compareToIndex) { ${T.primitive} compareTo = values[compareToIndex]; int length = Math.min(needle.length, compareTo.length); for (int i = 0; i < length; i++) { if (needle[i] != compareTo[i]) { if (needle[i] > compareTo[i]) { return 1; } else if (needle[i] < compareTo[i]) { return -1; } } } return needle.length - compareTo.length; }</#if> /** * Grows the backing array to the requested size. * * @param requested the new capacity. */ private void ensureCapacity(int requested) { // If we need to resize if(requested>values.length){ // Calculate the new size, growing slowly at the start to avoid overallocation too early. int newSize=Math.max(requested,(int)(values.length*SCALE_FACTOR+1)); <#if T.kind=="integerArray">${T.primitive}[]newValues=new ${arrayPrimitive}[newSize][];<#else> // Create the new array ${T.primitive}[]newValues=new ${T.primitive}[newSize];</#if> // Populate the new backing array System.arraycopy(values,0,newValues,0,size);values=newValues;} } /** * Retrieves the element at the requested index. * * @param index the element index you wish to retrieve * @return the value at that index */ public ${T.primitive} get(int index) { if (index >= size) { throw new ArrayIndexOutOfBoundsException("Attempted to access index " + index + " but array is " + size + " elements"); } return values[index]; } /** * Searches the list for the nominated value. * * @param searchFor the value you are looking for * @return the first index the value was found at or -1 if not found */ public int indexOf(${T.primitive}searchFor) { // Check each of the values. Don't bother with get() since we don't need its protection. for (int i = 0; i < size; i++) { <#if T.kind == "integerArray"> if (Arrays.equals(values[i], searchFor)) { <#elseif T.kind == "comparable"> if (values[i].equals(searchFor)) { <#else> if (values[i] == searchFor) { </#if> return i; } } // Didn't find it. return -1; } /** * Simple iterator that runs over the values in the list. */ private static final class InternalIterator implements Iterator<${T.clazz}> { private ${T.primitive}[] values; private int size; private int current = 0; private InternalIterator(${T.primitive}[]values, int size) { this.values = values; this.size = size; } /** * {@inheritDoc} */ @Override public boolean hasNext() { return current < size; } /** * {@inheritDoc} */ @Override public ${T.clazz} next() { if (!hasNext()) { throw new NoSuchElementException(); } return values[current++]; } /** * Not supported. */ @Override public void remove() { throw new UnsupportedOperationException("remove() is not supported"); } } /** * Returns an iterator over the underlying content. Note that this is completely unsynchronised and the contents can change under you. */ @Override public Iterator<${T.clazz}> iterator() { return new InternalIterator(values, size); } /** * Checks if the list is empty. * * @return true if the list is empty */ @Override public boolean isEmpty() { return size == 0; } /** * Sets the specified index to the nominated value. * * @param index the list index * @param newValue the value */ public void set(int index,$ { T.primitive }newValue) { if(index>=size){throw new ArrayIndexOutOfBoundsException("Attempted to access index "+index+" but array is "+size+" elements");}<#if(T.kind=="integerArray")>totalElementsHeapSize-=ClassSize.ARRAY+(values[index]!=null?values[index].length*Bytes.SIZEOF_${arrayPrimitive?upper_case}:0);</#if> values[index]=newValue; <#if(T.kind=="integerArray")>totalElementsHeapSize+=ClassSize.ARRAY+(newValue!=null?newValue.length*Bytes.SIZEOF_${arrayPrimitive?upper_case}:0);</#if> } <#if T.clazz!="byte[]"> @Override public void set(int index, byte[] newValue) { set(index, fromBytes(newValue)); }</#if> /** * Removes the specified index from the list. * * @param index the index to remove * @return the original value */ public $ { T.primitive } remove(int index) { if (index >= size) { throw new ArrayIndexOutOfBoundsException("Attempted to access index " + index + " but array is " + size + " elements"); } ${T.primitive} original = values[index]; System.arraycopy(values, index + 1, values, index, size - index - 1); size--; <#if (T.kind == "integerArray")> totalElementsHeapSize -= ClassSize.ARRAY + (original != null ? original.length * Bytes.SIZEOF_${arrayPrimitive?upper_case}: 0); </#if> return original; } /** * Inserts at the specified index to the list. * * @param index the index to insert * @param newValue the value to insert */ public void insert(int index,$ { T.primitive }newValue) { if(index>size){throw new ArrayIndexOutOfBoundsException("Attempted to access index "+index+" but array is "+size+" elements");} ensureCapacity(size+1);if(index!=size){System.arraycopy(values,index,values,index+1,size-index);}values[index]=newValue;size++;<#if(T.kind=="integerArray")>totalElementsHeapSize+=ClassSize.ARRAY+(newValue!=null?newValue.length*Bytes.SIZEOF_${arrayPrimitive?upper_case}:0);</#if> } <#if T.clazz!="byte[]"> @Override public void insert(int index, byte[] newValue) { insert(index, fromBytes(newValue)); }</#if> /** * Removes the last item in the list. * * @return the original value */ public $ { T.primitive } removeLast() { if (size < 1) { throw new ArrayIndexOutOfBoundsException("Attempted to remove last element from array with size 0"); } ${T.primitive} result = values[size - 1]; size--; <#if (T.kind == "integerArray")> values[size] = null; totalElementsHeapSize -= ClassSize.ARRAY + (result != null ? result.length * Bytes.SIZEOF_${arrayPrimitive?upper_case}: 0); </#if> return result; } /** * Returns the current number of elements in this list. * * @return the number of elements. */ public int size() { return size; } <#if T.clazz=="Byte">@Override public $ { T.clazz } fromBytes(byte[] bytes) { assert bytes.length == 1; return bytes[0]; }<# elseif T.clazz=="byte[]">@Override public $ { T.clazz } fromBytes(byte[] bytes) { return bytes; }<# elseif T.clazz=="char[]">@Override public $ { T.clazz } fromBytes(byte[] bytes) { return Bytes.to${arrayPrimitive?cap_first}s(bytes); }<#else>@Override public $ { T.clazz } fromBytes(byte[] bytes) { return Bytes.to${T.primitive?cap_first}(bytes); }</#if> <#if(T.kind=="integerArray")> @Override public long heapSize() { return FIXED_OVERHEAD + Bytes.SIZEOF_LONG + ClassSize.REFERENCE * values.length + totalElementsHeapSize; }<# elseif T.clazz=="BigDecimal"> @Override public long heapSize() { // take a rough estimate that a big decimal's overhead is 50 bytes. // TODO fix return FIXED_OVERHEAD + Bytes.SIZEOF_LONG + (ClassSize.REFERENCE + 50) * values.length; }<#else> @Override public long heapSize() { return FIXED_OVERHEAD+Bytes.SIZEOF_${T.primitive?upper_case}*values.length; }</#if> /** * Return a nice view of the list. * {@inheritDoc} */ @Override public String toString() { return Arrays.toString(Arrays.copyOf(values, size)); } /** * Checks the contents of the collection for equality. * <p/> * {@inheritDoc} */ @Override public boolean equals(Object compareTo) { if(this==compareTo){return true;}if(!(compareTo instanceof ${T.displayName}ArrayList)){return false;} ${T.displayName}ArrayList that=(${T.displayName}ArrayList)compareTo; return this.size==that.size&&ArrayUtils.isEquals(this.values,that.values); } /** * {@inheritDoc} */ @Override public int hashCode() { return 31 * Arrays.hashCode(values) + size; } }</#list>