Hi, welcome to JasperのBlog!
Collection system
Collection system considerations
- List interface: orderly (the order of adding is consistent with the order of traversal), subscript and repeatable elements.
- Set interface: unordered (the order of adding and traversal are inconsistent), no subscript, and elements cannot be repeated.
Collection parent interface
Collection method
Collection case implementation
public class CollectionTest { public static void main(String[] args) { Collection collection=new ArrayList(); System.out.println("-----isEmpty------"); //isEmpty determines whether the collection has elements. It returns true but not false System.out.println(collection.isEmpty()); System.out.println("-----add------"); //add adds an element to the collection Student s1=new Student("Zhang San",18); Student s2=new Student("Li Si",19); Student s3=new Student("Wang Wu",20); Student s4=new Student("Sun Liu",21); Student s5=new Student("Zhao Qi",22); collection.add(s1); collection.add(s2); collection.add(s3); collection.add(s4); collection.add(s5); System.out.println(collection); System.out.println("-----size------"); //size returns the number of elements in the collection System.out.println(collection.size()); System.out.println("-----remove------"); collection.remove(s3); System.out.println(collection); System.out.println("------removeAll-----"); //colletion.removeAll(Collection C) //Delete all elements that are also included in C from the collection Student s6=new Student("Liu Ba",23); Collection collection2=new ArrayList(); collection2.add(s4); collection2.add(s6); collection.removeAll(collection2); System.out.println(collection); System.out.println("------retainAll-----"); //colletion.retainAll(Collection C) //Only those elements in the collection that are also contained in C are retained //True is returned when there is no intersection, true is returned when there is intersection but not all intersection, and false is returned when two sets are equal Student s7=new Student("Lin Jiu",24); Collection collection3=new ArrayList(); collection3.add(s7); collection3.add(s1); collection3.add(s2); System.out.println(collection); System.out.println("Intersection:"+collection.retainAll(collection3)); Collection none=new ArrayList(); Collection test=new ArrayList(); test.addAll(collection); System.out.println("No intersection:"+test.retainAll(none)); test.addAll(collection); System.out.println("Two sets are equal:"+test.retainAll(test)); System.out.println("------contains-----"); //Whether contains contains this element returns true, not false System.out.println(collection.contains(s2)); //If conrtains (new object), it is equivalent to opening up a new space, which is different from the original s2 System.out.println(collection.contains(new Student("Li Si",19))); System.out.println("------containsAll-----"); //colletion.containsAll(Collection C) //If the collection contains T, all elements return true, otherwise return false Collection collection4=new ArrayList(); collection4.add(s1); System.out.println(collection.containsAll(collection4)); System.out.println("------equals and hashcode-----"); //equals determines whether the addresses of each element of two sets are equal System.out.println(collection); Collection collection5=new ArrayList(); collection5.add(s1); collection5.add(new Student("Li Si",19)); Collection collection6=new ArrayList(); collection6.add(s1); collection6.add(s2); System.out.println("collection"+collection.hashCode()); System.out.println("collection5"+collection5.hashCode()); System.out.println("collection6"+collection6.hashCode()); System.out.println(collection.equals(collection5)); System.out.println(collection.equals(collection6)); System.out.println("------addAll-----"); //colletion.addAll(Collection C) //Add all elements in C to colletion collection.addAll(collection2); System.out.println(collection); System.out.println("------ergodic-----"); //1. Enhance for traversal for (Object o : collection) { Student stu=(Student) o; System.out.printf("%s ",stu.getName()); } System.out.printf("\n"); //2. Iterator traversal Iterator it=collection.iterator(); while (it.hasNext()){ Student student = (Student) it.next(); System.out.printf("%s ",student.getName()); if (student.getName().equals("Liu Ba")){ it.remove(); } } System.out.printf("\n"); System.out.println(collection); System.out.println("------toArray-----"); //toArray() turns a collection into an array //toArray(T []) changes the collection to the specified T array Student[] t=new Student[5]; Student[] arr = (Student[]) collection.toArray(t); for (Student student : arr) { if (student!=null){ System.out.printf("%s ",student.getName()); } } System.out.printf("\n"); System.out.println("------clear-----"); //Clear clear collection elements System.out.println(collection); collection.clear(); System.out.println(collection.size()); } } class Student{ private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } } //Output results: -----isEmpty------ true -----add------ [Student{name='Zhang San', age=18}, Student{name='Li Si', age=19}, Student{name='Wang Wu', age=20}, Student{name='Sun Liu', age=21}, Student{name='Zhao Qi', age=22}] -----size------ 5 -----remove------ [Student{name='Zhang San', age=18}, Student{name='Li Si', age=19}, Student{name='Sun Liu', age=21}, Student{name='Zhao Qi', age=22}] ------removeAll----- [Student{name='Zhang San', age=18}, Student{name='Li Si', age=19}, Student{name='Zhao Qi', age=22}] ------retainAll----- [Student{name='Zhang San', age=18}, Student{name='Li Si', age=19}, Student{name='Zhao Qi', age=22}] Intersection: true No intersection: true Two sets are equal: false ------contains----- true false ------containsAll----- true ------equals and hashcode----- [Student{name='Zhang San', age=18}, Student{name='Li Si', age=19}] collection-1492222893 collection5-1698792011 collection6-1492222893 false true ------addAll----- [Student{name='Zhang San', age=18}, Student{name='Li Si', age=19}, Student{name='Sun Liu', age=21}, Student{name='Liu Ba', age=23}] ------ergodic----- Zhang San Li Si sun Liu Ba Zhang San Li Si sun Liu Ba [Student{name='Zhang San', age=18}, Student{name='Li Si', age=19}, Student{name='Sun Liu', age=21}] ------toArray----- Zhang San, Li Si, sun Liu ------clear----- [Student{name='Zhang San', age=18}, Student{name='Li Si', age=19}, Student{name='Sun Liu', age=21}] 0
It is worth noting that the equals method of the Collection is not overridden
class Fruit{ private String name; private String color; public Fruit(String name, String color) { this.name = name; this.color = color; } } public class ArrayListTest { public static void main(String[] args) { System.out.println("------Collection-------"); Collection c1=new ArrayList(); Fruit apple=new Fruit("Apple","red"); c1.add(apple); Collection c2=new ArrayList(); c2.add(new Fruit("Apple","red")); System.out.println(c1.equals(c2)); System.out.println(c1.hashCode()+" | "+c2.hashCode()); System.out.println("------Collection(String)-------"); Collection c3=new ArrayList(); Collection c4=new ArrayList(); c3.add(new String("Hello")); c4.add(new String("Hello")); System.out.println(c3.equals(c4));//Returns true because the string comparison overrides the equals method } } //Output results: ------Collection(obj)------- false 1554874533 | 1846274167 ------Collection(String)------- true
List interface
List method
List case implementation
public class ListTest { public static void main(String[] args) { List list= new ArrayList(); list.add(20);//Adding a base type automatically boxing list.add(40); list.add(50); System.out.println(list); System.out.println("-----add(int,E)-----"); list.add(1,60); System.out.println(list); System.out.println("-----addAll(int,E)-----"); List list2= new ArrayList(); list2.add(20); list2.add(80); list.addAll(2,list2); System.out.println(list); System.out.println("-----remove(int)-----"); list.remove(2); System.out.println(list); System.out.println("-----get(int)-----"); System.out.println(list.get(2)); System.out.println("-----set(int,E)-----"); list.set(1,50); System.out.println(list); System.out.println("-----lastIndexOf/indexOf(Object)-----"); System.out.println(list.indexOf(50)); System.out.println(list.lastIndexOf(50)); System.out.println("-----ergodic-----"); //1. Enhanced for 2 The iterator iterator inherits the Collection, and the two methods are the same //3.for loop for (int i=0;i<list.size();i++){ System.out.printf("%d ",list.get(i)); } System.out.println(); //4. Using the list iterator, unlike the iterator, listIterator can traverse forward or backward, add, delete and modify elements ListIterator listIterator = list.listIterator(); while (listIterator.hasNext()){ System.out.printf("[%d]:%d ",listIterator.nextIndex(),listIterator.next()); } System.out.println(); while (listIterator.hasPrevious()){ System.out.printf("[%d]:%d ",listIterator.previousIndex(),listIterator.previous()); } } } //Output results: [20, 40, 50] -----add(int,E)----- [20, 60, 40, 50] -----addAll(int,E)----- [20, 60, 20, 80, 40, 50] -----remove(int)----- [20, 60, 80, 40, 50] -----get(int)----- 80 -----set(int,E)----- [20, 50, 80, 40, 50] -----lastIndexOf/indexOf(Object)----- 1 4 -----ergodic----- 20 50 80 40 50 [0]:20 [1]:50 [2]:80 [3]:40 [4]:50 [4]:50 [3]:40 [2]:80 [1]:50 [0]:20
ArrayList implementation class
ArrayList method and case implementation
public class ArrayListTest { public static void main(String[] args) { ArrayList arr=new ArrayList(); Fruit apple=new Fruit("Apple","red"); Fruit banana=new Fruit("Banana","yellow"); Fruit orange=new Fruit("orange","orange"); arr.add(apple); arr.add(banana); arr.add(orange); System.out.println("------The collection contains references to objects-------"); apple.setName("Big apple"); System.out.println("Add to the collection and then change apple Name of"); System.out.println(arr); //The method of adding elements is the same as that of List, which will not be repeated here System.out.println("------remove(obj)-------"); //In the source code of remove element, the equals method is actually called. Mainly compare the addresses of the two //If you override Fruit's equals method, you will compare the contents of the two arr.remove(new Fruit("orange","orange")); System.out.println(arr); System.out.println("------ergodic-------"); //1. Enhanced for 2 Iterator iterator 3 Listiterator list iterator 4 for //In the reverse order of the list, first move the pointer to the tail, and then traverse from the tail to the head ListIterator listIterator = arr.listIterator(); while (listIterator.hasNext()){ listIterator.next(); } while(listIterator.hasPrevious()){ Fruit f=(Fruit) listIterator.previous(); System.out.printf("%s ",f.toString()); } System.out.println(); System.out.println("------contains(obj)-------"); System.out.println(arr.contains(new Fruit("Banana","yellow"))); System.out.println("------indexOf(obj)-------"); System.out.println(arr.indexOf(new Fruit("Banana","yellow"))); } } //Output results: ------The collection contains references to objects------- Add to the collection and then change apple Name of [Fruit{name='Big apple', color='red'}, Fruit{name='Banana', color='yellow'}, Fruit{name='orange', color='orange'}] ------remove(obj)------- [Fruit{name='Big apple', color='red'}, Fruit{name='Banana', color='yellow'}] ------ergodic------- Fruit{name='Banana', color='yellow'} Fruit{name='Big apple', color='red'} ------contains(obj)------- true ------indexOf(obj)------- 1
Data structure of ArrayList
- When analyzing a class, the data structure is often its soul. Understanding the underlying data structure actually understands the implementation idea of the class, and then analyze the specific implementation details. The underlying data structure of ArrayList is array. The array element type is Object type, which can store all types of data. All our operations on instances of the ArrayList class are based on arrays.
Source code analysis of ArrayList (JDK1.8)
Inheritance structure and hierarchy
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { ...... }
Why inherit AbstractList first and let AbstractList implement List first? Instead of having ArrayList implement List directly?
- Here is an idea that all interfaces are abstract methods, and abstract classes can have abstract methods and specific implementation methods. This is used to make AbstractList implement some general methods in the interface, and specific classes, such as ArrayList, inherit this AbstractList class and get some general methods, Then you are implementing some of your own unique methods. In this way, you can make the code more concise, extract the general methods in the classes at the bottom of the inheritance structure, and implement them together first to reduce repeated code. Therefore, it is generally seen that there is an abstract class above a class, which should be used for this purpose.
What interfaces does ArrayList implement
- List interface: some people explained it for the convenience of looking up the code.
- RandomAccess interface: it is used for fast random access. For efficiency problems, if the interface is implemented, the ordinary for loop is used to traverse, and the performance is higher.
- Cloneable interface: after implementing this interface, you can use object Clone() method.
- Serializable interface:
- Implement the serialization interface, indicating that the class can be serialized. What is serialization? In short, it can change from class to byte stream transmission, and then from byte to original class.
Properties in class
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { /** * Version number */ private static final long serialVersionUID = 8683452581122892189L; /** * Default initial capacity * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; /** * Empty object array * Shared empty array instance used for empty instances. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * Initial object array * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * Element array * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added. */ transient Object[] elementData; // non-private to simplify nested class access /** * The actual element size is 0 by default * The size of the ArrayList (the number of elements it contains). * @serial */ private int size; }
Construction method
Parameterless construction ArrayList()
//Constructs an empty list with an initial capacity of ten. //Construct an empty list with an initial capacity of 10 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
Parametrically structured ArrayList(int initialCapacity)
//Constructs an empty list with the specified initial capacity. //Construct an empty list and customize the initial capacity public ArrayList(int initialCapacity) { if (initialCapacity > 0) { //Customize initial capacity size this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { //Equivalent to parameterless construction method this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
ArrayList with parameters (collection <? Extensions E > C)
//Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator. //Constructs a list containing the elements of the specified collection in the order in which the collection iterator returns the elements public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); //The implementation method of toarray() of each collection is different, so you need to judge if it is not object [] Class type, you need to use the methods in ArrayList to transform it for so long. if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. //Equivalent to parameterless construction method this.elementData = EMPTY_ELEMENTDATA; } }
Source code analysis of add method
boolean add(E)
Case 1 parameterless initialization and adding an element
/* ArrayList arr = new ArrayList(); //This sentence can be understood as initializing an empty array arr.add(xxx); */ //Appends the specified element to the end of this list. //Add a specific element to the end of the list public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } /* Enter the function ensureCapacityInternal(size + 1); size Is the number of data in the array. Because you want to add an element, size+1 */ private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } /* Enter the function calculateCapacity(elementData, minCapacity); Where elementData is still an empty array, minCapacity = value of initial size + 1 = 1 */ private static int calculateCapacity(Object[] elementData, int minCapacity) { /* Note: if both a and b are arrays, then: a=b ,The comparison is the address a.equals(b) The comparison is the address Arrays.equals(a, b) The element content is compared When comparing two strings, it uses the equals() method under the String class, which compares the object value. When comparing the values of two Arrays, you need to use the equals() method in the Arrays class. That is, Arrays equals(a, b) */ //In the constructor, this elementData = DEFAULTCAPACITY_ EMPTY_ ELEMENTDATA; //So the if statement executes true math Max (10, 1) = 10 returns 10 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } /* Enter the function ensureCapacityInternal(int minCapacity); minCapacity=10 But note that the size of this elementData has not been really changed */ private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code // minCapacity=10 elementData.length=0, so mincapacity - elementdata length > 0 if (minCapacity - elementData.length > 0) grow(minCapacity); } /* Enter the function grow(minCapacity); minCapacity=10, which is the core function of array expansion */ private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //oldCapacity=0 int newCapacity = oldCapacity + (oldCapacity >> 1); //newCapacity= 0 + 0 = 0 //Newcapacity - mincapacity = - 10 < 0 execute the following if statement if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //newCapacity=10 //If the newCapacity exceeds the maximum capacity limit, call hugeCapacity, that is, give the maximum value that can be given to newCapacity if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); //minCapacity is usually close to size, so this is a win: //After the new capacity has been determined, change the capacity of the copy array elementData = Arrays.copyOf(elementData, newCapacity); } /* If newCapacity exceeds the maximum capacity limit, hugeCapacity is called */ private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); //If minCapacity is greater than MAX_ARRAY_SIZE, then integer MAX_ Value returns, otherwise MAX_ARRAY_SIZE return return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } /* Finally, go back and execute Boolean add (E) */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
Case 2 has parameters to initialize and add an element
/* ArrayList arr = new ArrayList(6); //The size of elementData is 6 arr.add(xxx); */ private static int calculateCapacity(Object[] elementData, int minCapacity) { //When this step is executed, the if statement does not hold and returns minCapacity=size+1=1 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code // minCapacity - elementData. Length = 1 - 6 < 0, so the grow th function will not be executed and the capacity will not be expanded if (minCapacity - elementData.length > 0) grow(minCapacity); }
Case 3 when no meal is initialized and the 11th element is added
/* ArrayList arr = new ArrayList(); //This sentence can be understood as initializing an empty array arr.add(xxx); : : arr.add(xxx); arr.add(xxx); 10 elements have been added. When you want to add the 11th element When the 10th element is added, execute elementData[size++] = e; It means elementData[size] = e, and then the size increases by 10 */ private static int calculateCapacity(Object[] elementData, int minCapacity) { //When this step is executed, the if statement does not hold and returns minCapacity=size+1=11 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code // minCapacity - elementData. Length = 11 - 10 > 0, so the grow th function will be executed to expand the capacity if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //oldCapacity=10 //Oldcapacity > > 1 indicates that the arithmetic is shifted to the right by 1 bit //For example, the binary of 10 is 01010, the arithmetic is shifted by 1 bit to the right, and 00101 is converted to hexadecimal 5 int newCapacity = oldCapacity + (oldCapacity >> 1); //newCapacity= 10 + 5 = 15 //newCapacity - minCapacity = 15 - 11 >0 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //If the newCapacity exceeds the maximum capacity limit, call hugeCapacity, that is, give the maximum value that can be given to newCapacity if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); //minCapacity is usually close to size, so this is a win: //After the new capacity has been determined, change the capacity of the copy array elementData = Arrays.copyOf(elementData, newCapacity); } public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; //Execute this line of code after capacity expansion return true; }
void add(int,E)
public void add(int index, E element) { //Check whether the index, that is, the insertion position is reasonable. rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! //Copy elementData from the element beginning with index to elementData, and copy from index + 1. The copy length is size - index System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } //rangeCheckForAdd(int index) private void rangeCheckForAdd(int index) { //The insertion position must not be greater than size and less than 0 if (index > size || index < 0) //If so, report this cross-border exception throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //void arraycopy public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
Source code analysis of remove method
remove(int)
public E remove(int index) { //Check the rationality of the index rangeCheck(index); modCount++; E oldValue = elementData(index);//Find the element directly by index int numMoved = size - index - 1;//Calculate the number of digits to move if (numMoved > 0) //Use system Arraycopy move copy element System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; }
remove(Object)
public boolean remove(Object o) { //Obviously, arrayList can store null values if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { //The internal of the fastRemove(index) method is almost the same as the implementation of remove(index) fastRemove(index); return true; } } return false; }
removeAll(collection c)
public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, false); } //batchRemove is the core method of removeAll. It is used in two places. If the complexity is false, it is used for removeAll; If true, it is used for retainAll(). retainAll() is used to detect whether two sets have an intersection. private boolean batchRemove(Collection<?> c, boolean complement) { final Object[] elementData = this.elementData; int r = 0, w = 0;//r is used to control the loop. w is the number of intersections of records. r and w can be regarded as two pointers to move between arrays boolean modified = false; try { for (; r < size; r++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. //Usually, if the program executes normally, r==size at last, if r= Size description: exceptions are reported during the use of the contains method if (r != size) { //The elements before r have been completed. Copy the start position of the r pointer of elementData to the start position of the w pointer of elementData, and copy the size - r length System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; //w pointer moves size - r units } //retainAll(): true is returned if there is no intersection, and true is returned if there is intersection but not all intersection. false is returned if the two sets are equal. Therefore, it is impossible to confirm whether there is intersection between the two sets according to the return value if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; }
Other methods
set(int,E)
public E set(int index, E element) { //Check whether the index is legal rangeCheck(index); //Find the old value E oldValue = elementData(index); //Assign new value elementData[index] = element; //Return old value return oldValue; }
indexOf(Object)
//Find whether the specified element exists in the array from the beginning public int indexOf(Object o) { if (o == null) { // Traverse the array, find the first empty element, and return the subscript for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { // Traverse the array, find the first element equal to the specified element, and return the subscript for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }
get(int) method
public E get(int index) { //Check whether the index is legal rangeCheck(index); //Returns the element value corresponding to the index return elementData(index); }