Java Array list stack - java

This is the top portion of my ArrayListStack class. I am trying to make values become an array list of T of 10. I am getting an error "incompatible types required: ArrayListStack found:java.util.ArrayList". In the line values = new ArrayList(10)". How would i properly set this value thanks
import java.util.ArrayList;
public class ArrayListStack<T> implements StackInterface<T>
{
private ArrayListStack<Integer> values= new ArrayListStack<Integer>();
private int size;
public ArrayListStack()
{
size = 0;
values = new ArrayList<T>(10);
}

I think you are attempting to use an ArrayList to back your ArrayListStack. It makes no sense for an ArrayListStack to contain another ArrayListStack. If this were to compile, each new ArrayListStack would create another ArrayListStack, which would create another ArrayListStack, etc.
Change the type of your values to ArrayList, and use your T generic type parameter:
private ArrayList<T> values;
No need to initialize it here; you are initializing it in the constructor.

There are multiple errors here:
you declare values as an ArrayListStack while it should be an ArrayList
you declare values by specifying the type parameter to Integer while it should stay T
you initialize values outside the constructor to inizialize it again inside the constructor
you try to initialize values to a different type, with a different type parameter
It should be
private ArrayList<T> values;
ArrayStackList() {
value = new ArrayList<T>(10);
}

You are assigning a generic type to an array list of Integer objects. Furthermore you are already initializing the list in your class definition.

public class ArrayListStack<T> implements StackInterface<T>
{
private ArrayList<T> values; // <-- Note change here
private int size;
public ArrayListStack()
{
size = 0;
values = new ArrayList<T>(10);
}
}
You need to have the same type and generic type for values when you construct it and when you declare it. T is your generic type (a generic generic type, if you will). I also removed the superfluous initialization at the field declaration, since you're re-constructing it in the constructor.

If you're trying to make a class that combines the functionality of ArrayList and StackInterface, make the following changes. Otherwise your code doesn't seem to make much sense
import java.util.ArrayList;
public class ArrayListStack<T> extends ArrayList<T> implements StackInterface<T>
{
public ArrayListStack()
{
//You can set this to whatever initial size you like,
//however if you look at the source code of ArrayList
//you'll discover that 10 is the default size of an ArrayList
super(10);
}
//Add whatever methods are required by StackInterface
}
In this situation, you can seamlessly use your class as both a standard ArrayList and a StackInterface

Related

Casting Object array to generic type

I am creating a stack of generic type that is backed by an array. When I try to make a generic type array, Java does not let me. I've been told that I must create an array of type Object and cast it to a generic type. I've casted my Object array to type , but how can I deal with the Unchecked Type error that Java keeps giving me?
public class AStack<T>{
// Create a stack with the default capacity 10. The stack expands
// its internal array when the number of elements pushed() into it
// would exceed the internal capacity.
Object arr[];
int top=-1;
public AStack(){
int defSize=10;
arr = (T[])new Object [defSize];
}
This is where I am so far.
UPDATE:
I am creating an Object array, then casting the return types to type T at the end of the method.
The simplest way is to use the type variable to cast array of objects to desired type.
public class AStack<T> {
T arr[];
int top=-1;
public AStack() {
int defSize=10;
arr = (T[]) new Object [defSize];
}
}
You could use an interface or a class that is extended to all the other classes you want to make generic and then use the interface or the class as the type of the array and now you could insert your specific types into the array.
GenericType[] array = { new specificType1(), new specificType2(), new specificType3() }

Generic array of complex types

for performance reasons I need to use arrays to store data. I implemented this in a generic fashion like this (see this answer):
import java.lang.reflect.Array;
public class SimpleArray<T> {
private T[] data;
#SuppressWarnings("unchecked")
public SimpleArray(Class<T> cls, int size) {
this.data = (T[]) Array.newInstance(cls, size);
}
public T get(int i) {
return data[i];
}
}
The problem is that I need the involved Class<?>es. However, I might have a more complex class hierarchy containing generics:
public class Outer<T> {
public class Inner {
}
}
I would like to initialize the array as I would with an ordinary class:
SimpleArray<Integer> intArray = new SimpleArray<>(Integer.class, 10);
intArray.get(0);
SimpleArray<Outer<Integer>> outerArray;
// how to initialize this?
SimpleArray<Outer<String>.Inner> innerArray;
// how to initialize this?
I read the post on how to (not) get the Class of something generic (here) but the bottom-line seems to be that everything is type-safety related syntactic sugar.
My question is the following: How can I create instances of the SimpleArray classes above while avoiding as much ugliness as possible?
There are two issues here.
Do you really need to pass in a Class? In this case, no. Your class does not actually need to know the element type at runtime to do its job. For example, you can just do:
public class SimpleArray<T> {
private Object[] data;
public SimpleArray(int size) {
this.data = new Object[size];
}
#SuppressWarnings("unchecked")
public T get(int i) {
return (T)data[i];
}
}
If you really needed a Class<T>, how would you get one? Well, first you need to ask yourself, what are you going to use this for? There will never be a "true" Class<T> for a non-reifiable type T because with a Class<T> you can do things like .isInstance() to check whether something is an instance of T at runtime; but of course it's not possible to check instance-of with non-reifiable types at runtime.
In this case, you're only going to pass it to Array.newInstance(), and Array.newInstance() uses the raw type anyway (it does not care about the compile-time type of the Class parameter -- the parameter type is Class<?> -- it only uses the runtime value of the Class object), it is sufficient to simply coerce a Class object representing the raw type to the appropriately-parameterized Class type:
(Class<Outer<Integer>>)(Class<?>)Outer.class
You seem to be trying to make a class that wraps an array and provides a method to get elements. The class Arrays.ArrayList does exactly that already, so there is no need to reinvent the wheel. It works as follows:
List<String> list = Arrays.asList(new String[30]);
list.set(3, "foo");
System.out.println(list.get(3));
You can't use Arrays.asList to produce a List<T> if the type T is generic without suppressing a warning because it is not possible to create a generic array. You can write a helper method to do this for you though.
#SuppressWarnings("unchecked")
public static <T> List<T> newArray(int size) {
return (List<T>) Arrays.asList(new Object[size]);
}
You can use the returned List to get and set elements without having to cast, even if the type T is generic. For example:
List<List<String>> list = newArray(30);
list.set(4, Arrays.asList("A", "B", "C"));
System.out.println(list.get(4));

Trying to create and test a comparable arraylist class

Here's the code I have. I'm trying to test out my bubbleSort Method..
import java.util.ArrayList;
import java.util.List;
public class MyArrayList<T extends Comparable<? super T>> extends ArrayList<Comparable<T>> {
private static final long serialVersionUID = 1L;
private MyArrayList<T> myList; // class list
public MyArrayList(ArrayList<Comparable<T>> asList) {
for (Comparable<T> e: asList) {
myList.add(e);
}
}
public void bubbleSort() {
boolean swapped = true;
while (swapped) {
swapped = false;
for (int i = 0; i < this.size() - 1; i++) {
if (this.get(i).compareTo((T) this.get(i + 1)) > 0) {
swapped = true;
Comparable<T> temp = this.get(i);
this.set(i, this.get(i + 1));
this.set(i + 1, temp);
}
}
}
}
}
In my test class, I am having trouble creating lists to test my bubbleSort method. I want to try to create an Integer list (from an array), a String list, and a few others, but I keep getting various errors.
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
public class MyArrayListTest<T> {
public void setUp() {
Integer[] testIntArray = new Integer[]{0, 1, 2, 3};
MyArrayList<Integer> myList = new MyArrayList<Integer>(Arrays.asList(testIntArray));
}
}
Any ideas why this doesn't work, and how I would go about creating a MyArrayList?
You should change your constructor from:
public MyArrayList(ArrayList<Comparable<T>> asList)
to:
public MyArrayList(List<T> asList)
Arrays.asList doesn't return a java.util.ArrayList, which is why new MyArrayList<Integer>(Arrays.asList(testIntArray)) doesn't compile. Arrays.asList returns an instance of a nested class defined inside the Arrays class, which is also called ArrayList, but more importantly, the return type of Arrays.asList(T... a) is List<T>.
Several problems here.
First, once you declared the base type of the list to be comparable, you shouldn't be using Comparable<T> anymore. This is actually what breaks your constructor. It expects a list of Comparable of something, and gets a list of Integer. Although an Integer is a Comparable, a List<Integer> is not a List<Comparator>. These are two different types.
Second, as you were told, the method Arrays.asList() returns a List and that's not assignment-compatible to ArrayList without type casting (and will fail on type casting, because it's not a java.util.ArrayList).
So the declaration of your constructor should actually be
public MyArrayList(List<T> asList)
And your loop variable e should also be declared as T. The basic fact is that Java already knows that T extends Comparable so it knows it has a compareTo() method.
But you also have a logical error which you have not ran into so far because of the constructor declaration. You actually have two collections in a MyArrayList. One is the field myList, and the other is this. Since you are extending an ArrayList, this is an ArrayList.
In your constructor, you add data to myList. But in your sort method, you are comparing and swapping the data in this! This means that it will probably attempt to sort an empty list, as you didn't fill it up in the constructor (unless you call its add method from your main).
In fact, adding information to myList will probably throw a NullPointerException as you did not initialize myList and you have no way of doing so as it is a MyArrayList, and has only the List-based constructor, which, if you will use, will send you on an infinite loop and end up with a Stack Overflow.
The list itself should probably extend ArrayList<T> rather than ArrayList<Comparable<T>>. Again, T is already known to extend Comparable. And then you could declare the temp variable T rather than Comparable<T>. It should also be unnecessary to cast the argument to T as it will already be T, being the base type of this.

Why does this constructor that uses generics fail?

I am creating a class that, at present, stores lists of various types in an internal object called genericTable. Each list (composed of either Double, or Long) are all held in an object which is an instance of class GenericList.
Question: Why doesn't the method addVector work?
The error under the red underline says the constructor Test<V>.GenericList<V>(List<List<V>>) is undefined.
If I was working in a main method (but had the same GenericList class) and created genericTable within the main method (using List<GenericList<?>> Table = new ArrayList<GenericList<?>>();) and did genericTable.add(new GenericList<Long>(Arrays.asList(genericVector))); (where genericVector in this case is a List<Long>), it works perfectly.
public class Test<V> {
private final List<GenericList<?>> genericTable = new ArrayList<GenericList<?>>();
public void addVector(List<V> genericVector) {
genericTable.add(new GenericList<V>(Arrays.asList(genericVector)));
}
private class GenericList<K> {
private final List<K> listGeneric;
public GenericList(List<K> input) {
listGeneric = input;
}
}
}
You're unnecessarily using Arrays.asList(), when you already have a list. Consequently you get a list of lists, which is not what the constructr accepts.
See this from the javadocs:
This method also provides a convenient way to create a fixed-size list
initialized to contain several elements:
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
So in your case you're getting a list of lists, instead of a list of strings.
I've added this bit from the comments, for clarity:
The method signature for asList() is like this:-
public static <T> List<T> asList(T... a)
So because T... a is a vararg, when you pass in "Larry", "Moe", "Curly", the compiled method actually receives an array of ["Larry", "Moe", "Curly"], and returns them as a List.
So because you passed in a List, rather than an array, the method takes the vararg array like this: [genericVector], and returns that array as a list, and you constructor breaks.

Java generics and arrays construction

Suppose I have a generic class with a generic parameter T which is a Number subclass. I would like to initialize an array of T during class construction. Is it possible? If yes how? If not why?
public class AClass<T extends Number>{
private T array[];
private int arrayOfInt[];
public AClass(int size){
arrayOfInt = new int[size];
array = ? //what should I put here?
}
}
T is only know at compile time. It is not know at runtime and thus you cannot initilise the contents of the array. However you can create the array, every value will be null.
array = (T[]) new Number[size];
EDIT: The problem with creating instances of any type is you need to know what is the default value you want and which constructor you want to call. e.g. there is no new Double()
As mentioned below, double[] will be more efficient and faster than Number[] and unless you need large long values, it will be able to store every possible value.
If you want to use arrays, there are two options:
Peter Lawrey's answer, array = (T[]) new Number[size];. You have to make sure never to return or pass this variable to code outside of the class that expect it to be an array of a particular type, which will cause an exception.
Declare array as type Number[], then just do array = new Number[size];. The downside of this is that when you get anything out of it you will need to explicitly cast to T to use it as such.
The two are the same after type erasure, and they will both cause unchecked cast warning, so it's really a matter of personal preference. The former is more convenient, while the latter is more formally correct (you are not pretending it's a type it's not).
Alternately, some people will tell you to use an ArrayList<T> instead. But internally, an ArrayList is still implemented using one of these two options.
This is not possible.
Because Java generics use type erasure, the type of T isn't known at runtime, so you can't create an array of it.
Other options than mentioned are to use toArray(T[]) or java.lang.reflect.Array:
public class AClass<T extends Number>{
private T array[];
public AClass(final int size, T[] a){
array = (new ArrayList<T>() {{
for (int i = 0; i < size; i++) {
add(null);
}
}}).toArray(a);
}
public AClass(int size, Class<T[ ]> clazz) {
array = clazz.cast(java.lang.reflect.Array.newInstance(
clazz.getComponentType( ), size));
}
public static void main(String[] args) {
System.out.println("toArray: "
+ new AClass<Double>(42, new Double[]{}).array.length);
System.out.println("java.lang.reflect.Array: "
+ new AClass<Double>(42, Double[].class).array.length);
}
}
PS. solution using reflection is close to one suggested in Langer's Generics FAQ (Utilities.createBuffer): How do I generically create objects and arrays?

Categories

Resources