I don't understand this line:
interface DataStructureIterator extends java.util.Iterator<Integer> { }
since there is no difference between DataStructeIterator and iterator can't we just remove this line and instead say:
private class EvenIterator implements java.util.iterator<Integer> { //code goes here}
What am I missing?
public class DataStructure {
// Create an array
private final static int SIZE = 15;
private int[] arrayOfInts = new int[SIZE];
public DataStructure() {
// fill the array with ascending integer values
for (int i = 0; i < SIZE; i++) {
arrayOfInts[i] = i;
}
}
public void printEven() {
// Print out values of even indices of the array
DataStructureIterator iterator = this.new EvenIterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
interface DataStructureIterator extends java.util.Iterator<Integer> { }
// Inner class implements the DataStructureIterator interface,
// which extends the Iterator<Integer> interface
private class EvenIterator implements DataStructureIterator {
// Start stepping through the array from the beginning
private int nextIndex = 0;
public boolean hasNext() {
// Check if the current element is the last in the array
return (nextIndex <= SIZE - 1);
}
public Integer next() {
// Record a value of an even index of the array
Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]);
// Get the next even element
nextIndex += 2;
return retValue;
}
}
public static void main(String s[]) {
// Fill the array with integer values and print out only
// values of even indices
DataStructure ds = new DataStructure();
ds.printEven();
}
}
Yes, you're right; for most purposes you can do away with the DataStructureIterator and use Iterator<Integer> directly.
Defining DataStructureIterator like this creates a shorthand notation for Iterator<Integer>, but it's a very poor shorthand. It's not at all like, for example, a typedef in C.
You can assign any object that implements DataStructureIterator to Iterator<Integer>, but you cannot assign all objects that implement Iterator<Integer> to DataStructureIterator.
So, although it's legal to define an empty interface like that, there is not much point to it. And it can lead to confusion.
Related
While going through the Effective Java examples, I failed to understand below code.
How this anonymous Abstract class return List of objects without iterating through array elements or calling the add() method.
what's going on behind the scenes in below code?
public static void main(String[] args) {
int a[] = new int[10];
for (int i = 0; i < a.length; i++) {
a[i] = i;
}
List<Integer> list = intArrayAsList(a);
System.out.println(list);
}
static List<Integer> intArrayAsList(final int[] a) {
if (a == null) {
throw new NullPointerException();
}
return new AbstractList<Integer>() {
#Override
public Integer get(int index) {
return a[index];
}
#Override
public int size() {
return a.length;
}
#Override
public Integer set(int index, Integer element) {
int oldVal = a[index];
a[index] = element;
return oldVal;
}
};
}
The reason add wasn't called is because it never created a new list. The new AbstractList is just holding a reference to the array 'a' and when you iterate over your new AbstractList, it will simply lookup in the array.
For fun, try to remove the keyword 'final' from that line:
static List<Integer> intArrayAsList(final int[] a) {
It will not compile anymore. The reason is because the AbstractList is an anonymous class and in order to be able to use a variable, that variable needs to be final.
new AbstractList<Integer>() { ... } is not an abstract class. It is a subclass of the abstract type AbstractList<Integer>. That particular type implements almost all List<Integer> methods in terms of just two abstract methods: get and set (size is also needed for some operations), whose implementation is provided by your example.
In particular, there was no need to call the add method because the provided implementation is a closure wrapping the supplied int[]. The AbstractList's implementation of iterator() will internally delegate to the provided implementation of get.
Hi I'm very new to Java and in this code, I think I'm not creating the Bag correctly in the Main? Please help thanks!
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
at mid.Bag.(Bag.java:12)
at mid.Bag.main(Bag.java:91)
public class Bag<T extends Comparable<T>> implements Iterable<T> {
private int MAX_ITEMS = 10; // initial array size
private int size;
private T[] data;
public Bag( ) {
data = (T []) new Object[MAX_ITEMS];
size = 0;
}
public void add(T newItem) {
// check if it's full, then extend (array resizing)
if (size == data.length) {
T[ ] temp = (T [ ] ) new Object[data.length*2];
for (int i = 0; i < size; ++i)
temp[i] = data[i];
// reassign data to point to temp
data = temp;
}
// then do the assignment
data[size++] = newItem; // assign newItem in the next-available slot
}
public Iterator<T> iterator() {
return new BagIterator();
}
/***************************
* nested class BagIterator
***************************/
class BagIterator implements Iterator<T> {
// instance member
private int index;
// (0) constructor
public BagIterator() {
index = 0;
}
// (1)
public boolean hasNext() {
return (index < size); // size in the outer Bag<E>
}
// (2)
public T next() {
/*
T temp = data[index]; // save the element value
index++; // increment index
return temp;
*/
return data[index++];
}
public static void main(String[ ] args) {
Bag<String> bag1=new Bag<String>();
bag1.add("good");
bag1.add("fortune");
bag1.add("billionarie");
for (String x: bag1)
System.out.println(x);
}
Yes, you're creating an Object[] and then trying to cast it to T[], which the compiler is converting to a cast to Comparable[] (using the raw Comparable type) due to your constraint on T.
Arrays and generics don't work terribly nicely together, basically.
It would probably be simpler to make your data field just an Object[] and cast individual values where necessary.
Here:
data = (T []) new Object[MAX_ITEMS];
you are constructing an Object array and trying to cast it to T[]. But you have declared that T inherits from Comparable. So use:
data = (T []) new Comparable[MAX_ITEMS];
You can probably rewrite your constructor as well:
public Bag(Class<T> c, int s) {
// Use Array native method to create array of a type only known at run time
#SuppressWarnings("unchecked")
final T[] dataArray = (T[]) Array.newInstance(c, s);
this.data = dataArray;
}
Then you can use it like:
Bag<String> bag1 = new Bag<>(String.class,10);
That should also work, IMO. The instances of T must be comparable in any case.
I want to add an object to my array. I am trying to create a method so whenever it's called, it adds the generic type object. Here's my code:
public class ArrayObjects<E> implements SomeImp<E>{
private E[] list;
private int maxCapacity, currentSize;
public ArrayObjects(){
maxCapacity = 10;
array = (E[]) new Object[maxCapacity];
}
public void addObj(E obj){
array.add(obj); //Throws an error
}
}
Eclipse shows me an error though. It says "Cannot invoke add(E) on the array type E[ ]"
Does anyone know why does this happen? Do you know of an alternative of adding an object to my generic array?
Thank you!
EDIT:
When I create an instance of a class that instantiates ArrayObjects, and try to add a value to it, it doesn't do it. code:
import packageWhereArrayObjectsIs.*;
public class Test {
private ArrayObjects<Integer> list;
public Test() {
list = new ArrayObjects<Integer>();
Test();
}
private void TestOne() {
for(int i=1; i <= 10; i++)
list.addLast(i);
System.out.println("Should print 1 .. 10");
System.out.println(list);
}
}
The method add() does not exist for arrays. You must access array elements using the correct syntax []:
public void addLast(E obj) {
array[currentSize++] = obj;
}
In order for your list to print nicely, you'll want to add a toString() method to your ArrayObjects class:
public String toString() {
return Arrays.toString(array);
}
To iterate over the elements of your ArrayObjects, you can implement the Iterable interface:
public class ArrayObjects<E> implements Iterable<E>
This requires your class to have an iterator() method that returns an Iterator:
public Iterator<E> iterator() {
class It implements Iterator<E>
{
int position = -1;
public boolean hasNext() {
return position + 1 < currentSize;
}
public E next() {
return array[++position];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
return new It();
}
Finally, this code shows how you can now iterate over your list using an enhanced for loop:
ArrayObjects<Integer> list = new ArrayObjects<Integer>();
for (int i = 0; i < 10; i++) list.addLast(i);
for (Integer i: list) {
System.out.println("Iterating over list! Next element is " + i);
}
You should do something like this, assuming that your actual size is 1 when you add your first element BUT the position will be 0 because it's the first position of the array.
public boolean addObj(E obj){
if(actualSize == maxCapacity){
return false;
}
array[actualSize--] = obj;
return true;
}
I changed the return value to return false if there is no positions left in the array (considering that you won't remove any object in the middle).
Why do you need an array? Why not going with a List?
public class ArrayObjects<E> implements SomeImp<E>{
private List<E> list;
private int maxCapacity;
public ArrayObjects(){
maxCapacity = 10;
list = new ArrayList<E>();
}
public boolean addObj(E obj){
if(list.size() == maxCapacity){
return false;
}
list.add(obj);
return true;
}
}
See that using a List you won't have to deal with the actualSize.
EDIT: as Smac89 points out, it makes no sense to use a list. But keep in mind you will have to find an empty position if the array is not full.
import.util.Arrays;
public class AList<T> implements ListInterface<T>{
private T[] list;
private int numberOfEntries;
private static final int DEFAILT_INI_CAPACITY=25;
public AList()
{
this(DEFAILT_INI_CAPACIT);
}
public AList
{
numberOfEntries = 0;
// the cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] tempList = (T[])new Object[initialCapacity];
list = tempList;
}
public void add(T newEntry) {
ensureCapacity();
list[numberOfEntries] = newEntry;
numberOfEntries++;
} // end add
public int getLength() {
return numberOfEntries;
} // end getLength
public boolean isEmpty() {
return numberOfEntries == 0; // or getLength() == 0
} // end isEmpty
public T[] toArray() {
// the cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] result = (T[])new Object[numberOfEntries];
for (int index = 0; index < numberOfEntries; index++) {
result[index] = list[index];
} // end for
return result;
} // end toArray
Prolbems from Data Strucutre and Algorithum in Java by Frank.
On chapter 13 exercise 12 I'm stuck on the following:
the following method Reduce the size of the array:
private boolean isTooBig()
This method return true if the number if entries in the list is less than half the size of the array and the size of the array is greater than 20.
The second new method creates a new array that is three quarters the size of the current array and then copies the object in the list of the new array:
private void reduceArray()
My Attempt:
private boolean isTooBig()
{
int half = (2 / getLenght());;
return ((numberOfEntries < half) && (numberOfEntries > 20));
}
private void reduceArray()
{
private T[] list2;
stuck...
}
My question: I do not know what is The array that I am reducing.
After I reduce the array. I do not know how to copy an ArrayList to another ArrayList.
Also I am stuck on Main project one.
1) Write a program that thoroughly tests the class AList.
My attempt:
public class test {
public static void main(String[] args)
{
AList<integer> listOfInt = new AList<integer>();
listOfInt.add(1);
listOfInt.add(2);
System.out.println(listOfInt);
}
The output is the address of listOfInt, but I want the literal value 1,2 to be printed.
I am currently learning Java and for my inner classes practice, I played aroud the following code:
public class DataStructure {
// Create an array
private final static int SIZE = 15;
private int[] arrayOfInts = new int[SIZE];
public DataStructure() {
// fill the array with ascending integer values
for (int i = 0; i < SIZE; i++) {
arrayOfInts[i] = i;
}
}
public void printEven() {
// Print out values of even indices of the array
DataStructureIterator iterator = this.new EvenIterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
interface DataStructureIterator extends java.util.Iterator<Integer> { }
// Inner class implements the DataStructureIterator interface,
// which extends the Iterator<Integer> interface
private class EvenIterator implements DataStructureIterator {
// Start stepping through the array from the beginning
private int nextIndex = 0;
public boolean hasNext() {
// Check if the current element is the last in the array
return (nextIndex <= SIZE - 1);
}
public Integer next() {
// Record a value of an even index of the array
Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]);
// Get the next even element
nextIndex += 2;
return retValue;
}
public void setNextIndex(int i){
nextIndex=i;
}
}
public void print(DataStructureIterator iterator) {
// Print out values of odd indices of the array
//iterator = this.new EvenIterator();
iterator.setNextIndex(1);//**This line giving me compiler error that setNextIndex is undefined for type DataStructure.DataStructureIterator **
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
public EvenIterator createNewObject(){
return this.new EvenIterator();
}
public static void main(String s[]) {
// Fill the array with integer values and print out only
// values of even indices
DataStructure ds = new DataStructure();
System.out.println("Even Index");
ds.printEven();
System.out.println("Odd Index");
ds.print(ds.createNewObject());
}
}
I am passing a EvenIterator object to the method print(DataStructureIterator), as far as I know a iterator can refer to a EvenIterator object(since DataStructureIterator is a implemented by EvenIterator), though hasNext() and setNextIndex(int) are in the same class the reference iterator is able to access only hasNext.
How can I fix this bug?
Even though you are passing EvenIterator to the method print(DataStructureIterator), it is silently getting casted into DataStructureIterator. So if the setNextIndex(int) method is not declared in DataStructureIterator, you will not be able to access it.
The print method know its parameter is a DataStructureIterator. Is the method setNextIndex declared in that interface? If not, you must add it.