Instructor: Joanna Klukowska
Copyright 2020 Joanna Klukowska. Unless noted otherwise all content is released under a
Creative Commons Attribution-ShareAlike 4.0 International License.
Background image by Stewart Weiss
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
What makes this approach different from a linked lists approach?
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
What makes this approach different from a linked lists approach?
ArrayList<E>
= an array (that can store any type of data) + operations that make everything easy© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
What makes this approach different from a linked lists approach?
ArrayList<E>
= an array (that can store any type of data) + operations that make everything easyWhere did the pirate store his loot?
Dana L., 2018
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
What makes this approach different from a linked lists approach?
ArrayList<E>
= an array (that can store any type of data) + operations that make everything easyWhere did the pirate store his loot?
Dana L., 2018
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
public boolean add(E element) { if (size >= array.length) { // make a bigger array and copy over the elements E[] bigger = (E[]) new Object[array.length * 2]; System.arraycopy(array, 0, bigger, 0, array.length); array = bigger; } array[size] = element; size++; return true; }
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
public boolean add(E element) { if (size >= array.length) { // make a bigger array and copy over the elements E[] bigger = (E[]) new Object[array.length * 2]; System.arraycopy(array, 0, bigger, 0, array.length); array = bigger; } array[size] = element; size++; return true; }
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
public boolean add(E element) { if (size >= array.length) { // make a bigger array and copy over the elements E[] bigger = (E[]) new Object[array.length * 2]; System.arraycopy(array, 0, bigger, 0, array.length); array = bigger; } array[size] = element; size++; return true; }
arraycopy()
is linear, it runs in time proportional to the size of the arrayfor (int i = 0; i < size; i++) bigger[i] = array[i];
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
public boolean add(E element) { if (size >= array.length) { // make a bigger array and copy over the elements E[] bigger = (E[]) new Object[array.length * 2]; System.arraycopy(array, 0, bigger, 0, array.length); array = bigger; } array[size] = element; size++; return true; }
arraycopy()
is linear, it runs in time proportional to the size of the arrayfor (int i = 0; i < size; i++) bigger[i] = array[i];
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
In amortized analysis we are interested in the performance of a given operation on average - when we repeat the operation many time and calculate how much time it took divided by the number of repeats. (See Amortized Analysis on Wikipedia for more formal details.)
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
In amortized analysis we are interested in the performance of a given operation on average - when we repeat the operation many time and calculate how much time it took divided by the number of repeats. (See Amortized Analysis on Wikipedia for more formal details.)
The add at the end (append) operation for an ArrayList has an amortized time performance of O(1) as long as the array size in increased by a multiplicative factor, not an additive factor.
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
In amortized analysis we are interested in the performance of a given operation on average - when we repeat the operation many time and calculate how much time it took divided by the number of repeats. (See Amortized Analysis on Wikipedia for more formal details.)
The add at the end (append) operation for an ArrayList has an amortized time performance of O(1) as long as the array size in increased by a multiplicative factor, not an additive factor.
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
In amortized analysis we are interested in the performance of a given operation on average - when we repeat the operation many time and calculate how much time it took divided by the number of repeats. (See Amortized Analysis on Wikipedia for more formal details.)
The add at the end (append) operation for an ArrayList has an amortized time performance of O(1) as long as the array size in increased by a multiplicative factor, not an additive factor.
this means that we need to multiply the current size of an array by a constant to get the size of the bigger array: if N starts as 10, and the multiplicative constant is 2, the sizes will be: 10, 20, 40, 80, 160, ...
not add some constant to the current size: if N starts at 10, and the additive constant is 2, the sizes would be: 10, 12, 14, 16, 18, ...
© Joanna Klukowska. CC-BY-SA.
If we want to add an element to an arbitrary position in the list, we will need to shift the values that are there to the higher indexes to make room for it.
© Joanna Klukowska. CC-BY-SA.
If we want to add an element to an arbitrary position in the list, we will need to shift the values that are there to the higher indexes to make room for it.
© Joanna Klukowska. CC-BY-SA.
If we want to add an element to an arbitrary position in the list, we will need to shift the values that are there to the higher indexes to make room for it.
This operation is O(N) because we need to shift the elements by one position to the right (higher indexes).
© Joanna Klukowska. CC-BY-SA.
If we want to remove an element from an arbitrary position in the list, we will need to shift the values in the higher indexes to fill in the whole that remains after removing an element.
© Joanna Klukowska. CC-BY-SA.
If we want to remove an element from an arbitrary position in the list, we will need to shift the values in the higher indexes to fill in the whole that remains after removing an element.
© Joanna Klukowska. CC-BY-SA.
If we want to remove an element from an arbitrary position in the list, we will need to shift the values in the higher indexes to fill in the whole that remains after removing an element.
This operation is O(N) because we need to shift the elements by one position to the left (lower indexes).
ArrayList<E>
Objects for Equality© Joanna Klukowska. CC-BY-SA.
equals
method specificationThe equals
method in the ArrayList<E>
class is inherited from the
AbstractList<E>
class.
© Joanna Klukowska. CC-BY-SA.
equals
method specificationThe equals
method in the ArrayList<E>
class is inherited from the
AbstractList<E>
class.
public boolean equals(Object o)
Compares the specified object with this list for equality. Returns true if and
only if the specified object is also a list, both lists have the same size, and
all corresponding pairs of elements in the two lists are equal.
(Two elements e1
and e2
are equal if (e1==null ? e2==null : e1.equals(e2))
.)
In other words, two lists are defined to be equal if they contain the same elements
in the same order.
Implementation Requirements:
This implementation first checks if the specified object is this list.
If so, it returns true
; if not, it checks if the specified object is a list. If
not, it returns false
; if so, it iterates over both lists, comparing corresponding
pairs of elements. If any comparison returns false
, this method returns false
.
If either iterator runs out of elements before the other it returns false
(as
the lists are of unequal length); otherwise it returns true
when the
iterations complete.
Parameters:
o
- the object to be compared for equality with this list
Returns:
true
if the specified object is equal to this list
© Joanna Klukowska. CC-BY-SA.
equals
method specificationThe equals
method in the ArrayList<E>
class is inherited from the
AbstractList<E>
class.
public boolean equals(Object o)
Compares the specified object with this list for equality. Returns true if and
only if the specified object is also a list, both lists have the same size, and
all corresponding pairs of elements in the two lists are equal.
(Two elements e1
and e2
are equal if (e1==null ? e2==null : e1.equals(e2))
.)
In other words, two lists are defined to be equal if they contain the same elements
in the same order.
Implementation Requirements:
This implementation first checks if the specified object is this list.
If so, it returns true
; if not, it checks if the specified object is a list. If
not, it returns false
; if so, it iterates over both lists, comparing corresponding
pairs of elements. If any comparison returns false
, this method returns false
.
If either iterator runs out of elements before the other it returns false
(as
the lists are of unequal length); otherwise it returns true
when the
iterations complete.
Parameters:
o
- the object to be compared for equality with this list
Returns:
true
if the specified object is equal to this list
Note that this specification allows us to use equals
to compare different implementations
of a list, for example an ArrayList
instance with a LinkedList
instance. The only
requirement is that they contain the same elements in the same order.
© Joanna Klukowska. CC-BY-SA.
equals
method implementationThis is the code from AbstractList<E>
class.
public boolean equals(Object o) { if (o == this) //check if the specified object is this list return true; if (!(o instanceof List)) //check if the specified object is a list return false; //iterate over both lists, comparing corresponding pairs of elements ListIterator<E> e1 = listIterator(); ListIterator<?> e2 = ((List<?>) o).listIterator(); while (e1.hasNext() && e2.hasNext()) { E o1 = e1.next(); Object o2 = e2.next(); if (!(o1==null ? o2==null : o1.equals(o2))) return false; } return !(e1.hasNext() || e2.hasNext());}
© Joanna Klukowska. CC-BY-SA.
equals
method alternative implementationThis is an alternative implementation of the same method.
public boolean equals(Object o) { if (o == this) //check if the specified object is this list return true; if (!(o instanceof List)) //check if the specified object is a list return false; //check if lists are of the same length if (this.size() != ((List<?>) o).size() ) { return false; } //iterate over both lists, comparing corresponding pairs of elements for (int i = 0; i < this.size(); i++ ) { E o1 = this.get(i); Object o2 = ((List<?>) o).get(i); if (!(o1==null ? o2==null : o1.equals(o2))) return false; } return true;}
© Joanna Klukowska. CC-BY-SA.
equals
method alternative implementationThis is an alternative implementation of the same method.
public boolean equals(Object o) { if (o == this) //check if the specified object is this list return true; if (!(o instanceof List)) //check if the specified object is a list return false; //check if lists are of the same length if (this.size() != ((List<?>) o).size() ) { return false; } //iterate over both lists, comparing corresponding pairs of elements for (int i = 0; i < this.size(); i++ ) { E o1 = this.get(i); Object o2 = ((List<?>) o).get(i); if (!(o1==null ? o2==null : o1.equals(o2))) return false; } return true;}
What is the performance of this function?
ArrayList<E>
Summary© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
ArrayList<E>
is the size of the actual array used for storing data.ArrayList<E>
is the number of elements that have been stored in it.Capacity≥Size
ArrayList<E>
class does not do it).
But it can be reduced by an explicit call to trimToSize()
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
ArrayList<E>
is the size of the actual array used for storing data.ArrayList<E>
is the number of elements that have been stored in it.Capacity≥Size
ArrayList<E>
class does not do it).
But it can be reduced by an explicit call to trimToSize()
Amortized Performance
front | back | index in the middle | |
---|---|---|---|
adding | O(N) | O(1) | O(N) |
removing | O(N) | O(1) | O(N) |
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
ArrayList<E>
is the size of the actual array used for storing data.ArrayList<E>
is the number of elements that have been stored in it.Capacity≥Size
ArrayList<E>
class does not do it).
But it can be reduced by an explicit call to trimToSize()
Amortized Performance
front | back | index in the middle | |
---|---|---|---|
adding | O(N) | O(1) | O(N) |
removing | O(N) | O(1) | O(N) |
Performance for other functions
function | performance |
---|---|
get(index) |
O(1) |
set(index,element) |
O(1) |
size() |
O(1) |
isEmpty() |
O(1) |
clear() |
O(N) resets each value to null |
function | performance |
---|---|
contains(object) |
O(N) |
indexOf(object) |
O(N) |
equals() |
O(N) |
toArray() |
O(N) |
sort() |
O(N logN) |
© Joanna Klukowska. CC-BY-SA.
contains
and indexOf
Without looking at the source code of the ArrayList<E>
class, implement
the contains
and indexOf
methods.
Use the documentation to find out exactly what they are supposed to do.
Once you have your code, compare it to the one in the ArrayList<E>
class and
see how similar/different it is.
ArrayList<E>
code does )?© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
The contains()
and indexOf
methods provides a linear search for the ArrayList<E>
.
But we know that a binary search is much more efficient if the data is sorted.
Write a method boolean isSorted (ArrayList<E> list )
that determines if the
given list is sorted or not.
Write a method int binSearch(ArrayList<E> list, E key)
that performs the binary search
and returns the index of key
or -1 if the key
is not present in the list
.
Write a method int bestSearch(ArrayList<E> list, E key)
that first determines
if the list is sorted or not, and selects to either use binSearch
or indexOf
method
accordingly. What is the performance of this method? Is it better, worse or the same as
the performance of the indexOf
method?
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
The contains()
and indexOf
methods provides a linear search for the ArrayList<E>
.
But we know that a binary search is much more efficient if the data is sorted.
Write a method boolean isSorted (ArrayList<E> list )
that determines if the
given list is sorted or not.
Write a method int binSearch(ArrayList<E> list, E key)
that performs the binary search
and returns the index of key
or -1 if the key
is not present in the list
.
Write a method int bestSearch(ArrayList<E> list, E key)
that first determines
if the list is sorted or not, and selects to either use binSearch
or indexOf
method
accordingly. What is the performance of this method? Is it better, worse or the same as
the performance of the indexOf
method?
Note that the above methods are NOT part of the ArrayList<E>
class. They should be implemented
as stand alone methods.
Instructor: Joanna Klukowska
Copyright 2020 Joanna Klukowska. Unless noted otherwise all content is released under a
Creative Commons Attribution-ShareAlike 4.0 International License.
Background image by Stewart Weiss
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
What makes this approach different from a linked lists approach?
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
What makes this approach different from a linked lists approach?
ArrayList<E>
= an array (that can store any type of data) + operations that make everything easy© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
What makes this approach different from a linked lists approach?
ArrayList<E>
= an array (that can store any type of data) + operations that make everything easyWhere did the pirate store his loot?
Dana L., 2018
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
What makes this approach different from a linked lists approach?
ArrayList<E>
= an array (that can store any type of data) + operations that make everything easyWhere did the pirate store his loot?
Dana L., 2018
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
public boolean add(E element) { if (size >= array.length) { // make a bigger array and copy over the elements E[] bigger = (E[]) new Object[array.length * 2]; System.arraycopy(array, 0, bigger, 0, array.length); array = bigger; } array[size] = element; size++; return true; }
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
public boolean add(E element) { if (size >= array.length) { // make a bigger array and copy over the elements E[] bigger = (E[]) new Object[array.length * 2]; System.arraycopy(array, 0, bigger, 0, array.length); array = bigger; } array[size] = element; size++; return true; }
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
public boolean add(E element) { if (size >= array.length) { // make a bigger array and copy over the elements E[] bigger = (E[]) new Object[array.length * 2]; System.arraycopy(array, 0, bigger, 0, array.length); array = bigger; } array[size] = element; size++; return true; }
arraycopy()
is linear, it runs in time proportional to the size of the arrayfor (int i = 0; i < size; i++) bigger[i] = array[i];
© Joanna Klukowska. CC-BY-SA.
Adding to the end of an array is O(1), except for when we need to add to a completely full array when it is O(N).
public boolean add(E element) { if (size >= array.length) { // make a bigger array and copy over the elements E[] bigger = (E[]) new Object[array.length * 2]; System.arraycopy(array, 0, bigger, 0, array.length); array = bigger; } array[size] = element; size++; return true; }
arraycopy()
is linear, it runs in time proportional to the size of the arrayfor (int i = 0; i < size; i++) bigger[i] = array[i];
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
In amortized analysis we are interested in the performance of a given operation on average - when we repeat the operation many time and calculate how much time it took divided by the number of repeats. (See Amortized Analysis on Wikipedia for more formal details.)
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
In amortized analysis we are interested in the performance of a given operation on average - when we repeat the operation many time and calculate how much time it took divided by the number of repeats. (See Amortized Analysis on Wikipedia for more formal details.)
The add at the end (append) operation for an ArrayList has an amortized time performance of O(1) as long as the array size in increased by a multiplicative factor, not an additive factor.
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
In amortized analysis we are interested in the performance of a given operation on average - when we repeat the operation many time and calculate how much time it took divided by the number of repeats. (See Amortized Analysis on Wikipedia for more formal details.)
The add at the end (append) operation for an ArrayList has an amortized time performance of O(1) as long as the array size in increased by a multiplicative factor, not an additive factor.
© Joanna Klukowska. CC-BY-SA.
If the initial size of the array is N, then
Intuitively, we have N * O(1) + 1 * O(N) to add N+1 elements -> this is still a constant time for each operation (almost).
In amortized analysis we are interested in the performance of a given operation on average - when we repeat the operation many time and calculate how much time it took divided by the number of repeats. (See Amortized Analysis on Wikipedia for more formal details.)
The add at the end (append) operation for an ArrayList has an amortized time performance of O(1) as long as the array size in increased by a multiplicative factor, not an additive factor.
this means that we need to multiply the current size of an array by a constant to get the size of the bigger array: if N starts as 10, and the multiplicative constant is 2, the sizes will be: 10, 20, 40, 80, 160, ...
not add some constant to the current size: if N starts at 10, and the additive constant is 2, the sizes would be: 10, 12, 14, 16, 18, ...
© Joanna Klukowska. CC-BY-SA.
If we want to add an element to an arbitrary position in the list, we will need to shift the values that are there to the higher indexes to make room for it.
© Joanna Klukowska. CC-BY-SA.
If we want to add an element to an arbitrary position in the list, we will need to shift the values that are there to the higher indexes to make room for it.
© Joanna Klukowska. CC-BY-SA.
If we want to add an element to an arbitrary position in the list, we will need to shift the values that are there to the higher indexes to make room for it.
This operation is O(N) because we need to shift the elements by one position to the right (higher indexes).
© Joanna Klukowska. CC-BY-SA.
If we want to remove an element from an arbitrary position in the list, we will need to shift the values in the higher indexes to fill in the whole that remains after removing an element.
© Joanna Klukowska. CC-BY-SA.
If we want to remove an element from an arbitrary position in the list, we will need to shift the values in the higher indexes to fill in the whole that remains after removing an element.
© Joanna Klukowska. CC-BY-SA.
If we want to remove an element from an arbitrary position in the list, we will need to shift the values in the higher indexes to fill in the whole that remains after removing an element.
This operation is O(N) because we need to shift the elements by one position to the left (lower indexes).
ArrayList<E>
Objects for Equality© Joanna Klukowska. CC-BY-SA.
equals
method specificationThe equals
method in the ArrayList<E>
class is inherited from the
AbstractList<E>
class.
© Joanna Klukowska. CC-BY-SA.
equals
method specificationThe equals
method in the ArrayList<E>
class is inherited from the
AbstractList<E>
class.
public boolean equals(Object o)
Compares the specified object with this list for equality. Returns true if and
only if the specified object is also a list, both lists have the same size, and
all corresponding pairs of elements in the two lists are equal.
(Two elements e1
and e2
are equal if (e1==null ? e2==null : e1.equals(e2))
.)
In other words, two lists are defined to be equal if they contain the same elements
in the same order.
Implementation Requirements:
This implementation first checks if the specified object is this list.
If so, it returns true
; if not, it checks if the specified object is a list. If
not, it returns false
; if so, it iterates over both lists, comparing corresponding
pairs of elements. If any comparison returns false
, this method returns false
.
If either iterator runs out of elements before the other it returns false
(as
the lists are of unequal length); otherwise it returns true
when the
iterations complete.
Parameters:
o
- the object to be compared for equality with this list
Returns:
true
if the specified object is equal to this list
© Joanna Klukowska. CC-BY-SA.
equals
method specificationThe equals
method in the ArrayList<E>
class is inherited from the
AbstractList<E>
class.
public boolean equals(Object o)
Compares the specified object with this list for equality. Returns true if and
only if the specified object is also a list, both lists have the same size, and
all corresponding pairs of elements in the two lists are equal.
(Two elements e1
and e2
are equal if (e1==null ? e2==null : e1.equals(e2))
.)
In other words, two lists are defined to be equal if they contain the same elements
in the same order.
Implementation Requirements:
This implementation first checks if the specified object is this list.
If so, it returns true
; if not, it checks if the specified object is a list. If
not, it returns false
; if so, it iterates over both lists, comparing corresponding
pairs of elements. If any comparison returns false
, this method returns false
.
If either iterator runs out of elements before the other it returns false
(as
the lists are of unequal length); otherwise it returns true
when the
iterations complete.
Parameters:
o
- the object to be compared for equality with this list
Returns:
true
if the specified object is equal to this list
Note that this specification allows us to use equals
to compare different implementations
of a list, for example an ArrayList
instance with a LinkedList
instance. The only
requirement is that they contain the same elements in the same order.
© Joanna Klukowska. CC-BY-SA.
equals
method implementationThis is the code from AbstractList<E>
class.
public boolean equals(Object o) { if (o == this) //check if the specified object is this list return true; if (!(o instanceof List)) //check if the specified object is a list return false; //iterate over both lists, comparing corresponding pairs of elements ListIterator<E> e1 = listIterator(); ListIterator<?> e2 = ((List<?>) o).listIterator(); while (e1.hasNext() && e2.hasNext()) { E o1 = e1.next(); Object o2 = e2.next(); if (!(o1==null ? o2==null : o1.equals(o2))) return false; } return !(e1.hasNext() || e2.hasNext());}
© Joanna Klukowska. CC-BY-SA.
equals
method alternative implementationThis is an alternative implementation of the same method.
public boolean equals(Object o) { if (o == this) //check if the specified object is this list return true; if (!(o instanceof List)) //check if the specified object is a list return false; //check if lists are of the same length if (this.size() != ((List<?>) o).size() ) { return false; } //iterate over both lists, comparing corresponding pairs of elements for (int i = 0; i < this.size(); i++ ) { E o1 = this.get(i); Object o2 = ((List<?>) o).get(i); if (!(o1==null ? o2==null : o1.equals(o2))) return false; } return true;}
© Joanna Klukowska. CC-BY-SA.
equals
method alternative implementationThis is an alternative implementation of the same method.
public boolean equals(Object o) { if (o == this) //check if the specified object is this list return true; if (!(o instanceof List)) //check if the specified object is a list return false; //check if lists are of the same length if (this.size() != ((List<?>) o).size() ) { return false; } //iterate over both lists, comparing corresponding pairs of elements for (int i = 0; i < this.size(); i++ ) { E o1 = this.get(i); Object o2 = ((List<?>) o).get(i); if (!(o1==null ? o2==null : o1.equals(o2))) return false; } return true;}
What is the performance of this function?
ArrayList<E>
Summary© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
ArrayList<E>
is the size of the actual array used for storing data.ArrayList<E>
is the number of elements that have been stored in it.Capacity≥Size
ArrayList<E>
class does not do it).
But it can be reduced by an explicit call to trimToSize()
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
ArrayList<E>
is the size of the actual array used for storing data.ArrayList<E>
is the number of elements that have been stored in it.Capacity≥Size
ArrayList<E>
class does not do it).
But it can be reduced by an explicit call to trimToSize()
Amortized Performance
front | back | index in the middle | |
---|---|---|---|
adding | O(N) | O(1) | O(N) |
removing | O(N) | O(1) | O(N) |
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
ArrayList<E>
is the size of the actual array used for storing data.ArrayList<E>
is the number of elements that have been stored in it.Capacity≥Size
ArrayList<E>
class does not do it).
But it can be reduced by an explicit call to trimToSize()
Amortized Performance
front | back | index in the middle | |
---|---|---|---|
adding | O(N) | O(1) | O(N) |
removing | O(N) | O(1) | O(N) |
Performance for other functions
function | performance |
---|---|
get(index) |
O(1) |
set(index,element) |
O(1) |
size() |
O(1) |
isEmpty() |
O(1) |
clear() |
O(N) resets each value to null |
function | performance |
---|---|
contains(object) |
O(N) |
indexOf(object) |
O(N) |
equals() |
O(N) |
toArray() |
O(N) |
sort() |
O(N logN) |
© Joanna Klukowska. CC-BY-SA.
contains
and indexOf
Without looking at the source code of the ArrayList<E>
class, implement
the contains
and indexOf
methods.
Use the documentation to find out exactly what they are supposed to do.
Once you have your code, compare it to the one in the ArrayList<E>
class and
see how similar/different it is.
ArrayList<E>
code does )?© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
The contains()
and indexOf
methods provides a linear search for the ArrayList<E>
.
But we know that a binary search is much more efficient if the data is sorted.
Write a method boolean isSorted (ArrayList<E> list )
that determines if the
given list is sorted or not.
Write a method int binSearch(ArrayList<E> list, E key)
that performs the binary search
and returns the index of key
or -1 if the key
is not present in the list
.
Write a method int bestSearch(ArrayList<E> list, E key)
that first determines
if the list is sorted or not, and selects to either use binSearch
or indexOf
method
accordingly. What is the performance of this method? Is it better, worse or the same as
the performance of the indexOf
method?
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
The contains()
and indexOf
methods provides a linear search for the ArrayList<E>
.
But we know that a binary search is much more efficient if the data is sorted.
Write a method boolean isSorted (ArrayList<E> list )
that determines if the
given list is sorted or not.
Write a method int binSearch(ArrayList<E> list, E key)
that performs the binary search
and returns the index of key
or -1 if the key
is not present in the list
.
Write a method int bestSearch(ArrayList<E> list, E key)
that first determines
if the list is sorted or not, and selects to either use binSearch
or indexOf
method
accordingly. What is the performance of this method? Is it better, worse or the same as
the performance of the indexOf
method?
Note that the above methods are NOT part of the ArrayList<E>
class. They should be implemented
as stand alone methods.
© Joanna Klukowska. CC-BY-SA.
ArrayList<E>
as an Example of Array Based Implementation of a ListInstead of creating our own implementation that is based on an array, we will look
at the existing one implemented in Java: ArrayList<E>
class.
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |