This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 5 years ago.
I have problem with the toArray method. In this example i am using Integer and solved it by casting Integer, but the method should work for all types, without casting in main.
why cant i use one of these two in my main method?
arr = (T[]) a.toArray(arr) ;
or even
arr = a.toArray(arr)
I get a type mismatch: cannot convert from object[] to Integer[]
both size() and addFirst() works.
public static void main(String[] args) {
ArrayDeque a = new ArrayDeque(5);
a.addFirst(1);
a.addFirst(2);
Integer [] arr = new Integer[a.size()];
arr= (Integer[]) a.toArray(arr);
System.out.println(Arrays.toString(arr));
}
public class ArrayDeque<E> implements IDeque<E> {
private int counter= 0;
private E[] deque;
#SuppressWarnings("unchecked")
public ArrayDeque(int size) {
deque = (E[]) new Object[size];
}
public <E> E[] toArray(E[] a) {
return (E[]) Arrays.copyOf(deque, counter, a.getClass());
}
}
You are instantiating a raw type:
ArrayDeque a = new ArrayDeque(5);
change it to
ArrayDeque<Integer> a = new ArrayDeque<>(5);
This will remove the need to cast the returned array to Integer[].
P.S., it doesn't make sense for the toArray(E[] a) to define its own generic type parameter E. It should use the parameter defined in the class level.
You are instantiating a raw type when declaring the ArrayDeque a. You should parameterize it:
ArrayDeque<Integer> a = new ArrayDeque<Integer>(5);
a.addFirst(1);
a.addFirst(2);
Integer [] arr = new Integer[a.size()];
arr= a.toArray(arr);
Related
I was wondering why the sort method of the Arrays class is asking for a parameter of type Object[]. Why the parameter is not of type Comparable[]. If you don't pass a Comparable[] it's generating a ClassCastException.
Why ... public static void sort(Object[] a) and not public static void sort(Comparable[] a) ?
Thanks
Because the second form would require a reallocation of the array. Even if you know that your array contains only comparables, you cannot just cast it to Comparable[] if the original type was Object[], since the array type does not match.
You can do:
Object[] arr = new String[0];
String[] sarr = (String[]) arr;
But you can't do:
Object[] arr = new Object[0];
String[] sarr = (String[]) arr;
So it's premature optimization :)
Otherwise you can't pass Object[] in.
I am trying do something like this:-
public static ArrayList<myObject>[] a = new ArrayList<myObject>[2];
myObject is a class. I am getting this error:- Generic array creation (arrow is pointing to new.)
You can't have arrays of generic classes. Java simply doesn't support it.
You should consider using a collection instead of an array. For instance,
public static ArrayList<List<MyObject>> a = new ArrayList<List<MyObject>();
Another "workaround" is to create an auxilliary class like this
class MyObjectArrayList extends ArrayList<MyObject> { }
and then create an array of MyObjectArrayList.
Here is a good article on why this is not allowed in the language. The article gives the following example of what could happen if it was allowed:
List<String>[] lsa = new List<String>[10]; // illegal
Object[] oa = lsa; // OK because List<String> is a subtype of Object
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
oa[0] = li;
String s = lsa[0].get(0);
There is a easier way to create generic arrays than using List.
First, let
public static ArrayList<myObject>[] a = new ArrayList[2];
Then initialize
for(int i = 0; i < a.length; i++) {
a[i] = new ArrayList<myObject>();
}
You can do
public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList<?>[2];
or
public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList[2];
(The former is probably better.) Both will cause unchecked warnings, which you can pretty much ignore or suppress by using: #SuppressWarnings("unchecked")
if you are trying to declare an arraylist of your generic class you can try:
public static ArrayList<MyObject> a = new ArrayList<MyObject>();
this will give you an arraylist of myobject (size 10), or if u only need an arraylist of size 2 you can do:
public static ArrayList<MyObject> a = new ArrayList<MyObject>(2);
or you may be trying to make an arraylist of arraylists:
public static ArrayList<ArrayList<MyObject>> a = new ArrayList<ArrayList<MyObject>>();
although im not sure if the last this i said is correct...
It seems to me that you use the wrong type of parenthesis. The reason why you can't define an array of generic is type erasure.
Plus, declaration of you variable "a" is fragile, it should look this way:
List<myObject>[] a;
Do not use a concrete class when you can use an interface.
When I am passing an ArrayList to TreeSet constructor, I am getting the following error:
Exception in thread "main" java.lang.ClassCastException: [I cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
at java.util.TreeSet.addAll(TreeSet.java:312)
at java.util.TreeSet.<init>(TreeSet.java:160)
at jay.week1.MaxPairwiseProduct.getMaxPairwiseProduct(MaxPairwiseProduct.java:8)
at jay.week1.MaxPairwiseProduct.main(MaxPairwiseProduct.java:17)
I am getting the above error at this line :
TreeSet<Integer> set = new TreeSet(Arrays.asList(numbers));
This is the full program:
import java.util.*;
public class MaxPairwiseProduct {
static int getMaxPairwiseProduct(int[] numbers) {
TreeSet<Integer> set = new TreeSet(Arrays.asList(numbers));
int max1 = set.pollLast();
int max2 = set.pollLast();
int result = max1 * max2;
return result;
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
System.out.println(getMaxPairwiseProduct(numbers));
}
}
What is it that I am doing wrong?
What Arrays.asList() actually returning is list of int array.
List<int[]> list = Arrays.asList(numbers);
You need to do the following.
TreeSet<Integer> set = Arrays.stream(number).boxed()
.collect(Collectors.toCollection(TreeSet::new));
It is failing to do that because you can't have a TreeSet<int>, only a TreeSet<Integer>.
Because you did not specify a generic type for TreeSet, Arrays.asList tries to create a List<int[]>, which it succeeds. Why a int[]? You might ask. This is because int cannot be a generic type, so the generic parameter of asList is inferred to be int[], which can be a generic type. But then this list goes into TreeSet's constructor and TreeSet discovers that this is not a list of Integers, throwing an exception.
To fix this, you either change the parameter type from int[] to Integer[], or convert the int[] to a Integer[] before passing it into Arrays.asList.
TreeSet<Integer> set = new TreeSet<>(Arrays.stream(numbers).boxed().collect(Collectors.toList()));
This question already has answers here:
How to convert int[] into List<Integer> in Java?
(21 answers)
Closed 5 years ago.
Java compiler takes care of casting primitive data types and their wrapper classes..But my doubt is that although java compiler performs type casting all by itself, why is it that it prints an error when I try to convert an Array to ArrayList with int array as parameter..Like:
int[] val = {1,2,3,4,5};
ArrayList<Integer> newval = new ArrayList<Integer>(Arrays.asList(val));
Error: no suitable constructor found for ArrayList(List<int[]>)
Why is the compiler not casting int to Integer?
You can use a IntStream to help you with the "boxing" of primitives
int[] a = {1,2,3,4};
List<Integer> list = IntStream.of(a)
.boxed()
.collect(Collectors.toList());
This will iterate the array, boxed the int into an Integer and then you just have to collect the Stream into a List with the Collectors.
You can't create a ArrayList<primitive types> Source: why you can't create a Arraylist of primitive types. Instead, use an adaptor class:
class Adapter{
private int[] value;
adapter(int[] value){
this.value = value;
}
public int[] getValue(){
return value;
}
}
And then add it to the ArrayList<Adapter> AL = new ArrayList<>();
There is no autoboxing here; perhaps you meant to do:
Integer[] val = {1,2,3,4,5};
int[] val = {1,2,3,4,5};
For Primitive arrays:
List<int[]> vv = Arrays.asList(val);
Will get List of arrays because autoboxing wont work when we try to convert the primitive array into list
For Object array type:
Integer[] val = {1,2,3,4,5};
List<Integer> vv = Arrays.asList(val);
Compiler will use autoboxing
Arrays.asList accepts an array of objects - not primitives (in many cases the compiler is smart enough to interchange through something called autoboxing - in this case not). Using a simple loop you can add the items of the array to the List.
I am trying to make a generic function into which I pass an array (int[], String[]) and gets back the sorted version of it using TreeSort. I haven't even had the chance to begin to debug it since the mainclass refuses to accept an int[] array as the parameter.
TreeSort
public T[] treeSort(T[] arr) {
T[] result = (T[]) new Object[arr.length];
for (int i = 0; i < arr.length; i++)
if (arr[i] != null)
add(arr[i]);
Iterator it = iterator();
int count = 0;
while (it.hasNext())
result[count++] = (T) it.next();
return (T[]) result;
}
Main
BinarySearchTree<Integer> tree2 = new BinarySearchTree<>();
int[] unsortedNums = {6,3,7,4,1,2,9,8,5};
int[] sortedNums = tree2.treeSort(unsortedNums);
Error
The method treeSort(Integer[]) in the type BinarySearchTree is not applicable for the arguments (int[])
So I attempted to change unsortedNums and sortedNums from int to Integer (why should this matter?), and now running it yields this error:
Errorr 2
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
on line
T[] result = (T[]) new Object[arr.length];
In a generic method in Java, it is not allowed to create an array of the generic type. You are trying to circumvent this rule by creating an Object array and casting it to the generic type, but the compiler is too smart and prevents this. The reason for this rule is that the generic type could well be an Interface, so the runtime wouldn't know which class to create.
For your example, if you really need to keep the unsorted array as it is and return a copy (usually, sorting happens in-place so you would just edit the original array), you can either let the user pass the type of the generic (as in sp00m's answer), or let the user supply the destination array as a parameter so you don't need to create an array yourself.
IMO, the best practice here would be to make your sorting happen in place instead of returning a sorted copy of the data.
Instead of:
T[] result = (T[]) new Object[arr.length];
You have to use:
T[] result = (T[]) Array.newInstance(clazz, arr.length);
Where clazz is the type of the nested elements:
public T[] treeSort(T[] arr, Class<T> clazz) {...}
Finally, when calling, use the boxed primitive:
Integer[] unsortedNums = { 6, 3, 7, 4, 1, 2, 9, 8, 5 };
Integer[] sortedNums = treeSort(unsortedNums, Integer.class);
In Java, arrays know their component types at runtime (the component type is part of the actual runtime array type), and thus you need to specify the component type at runtime to create an array of that type.
#spoom's answer showed you how to create the array given a class object passed into the function. However, you actually already have that information without passing it separately. The parameter arr is of type T[], which means the array object's actual runtime type must be T[] or a subclass thereof. We can extract the component type from that and use it to create the new array:
T[] result = (T[]) Array.newInstance(arr.getClass().getComponentType(), arr.length);
This is how, for example, Arrays.copyOf() and related functions work.
You can't use primitive types (int) in generitcs. Try to use object wrapper, for example
Integer[] unsortedNums = {6,3,7,4,1,2,9,8,5};
Integer[] sortedNums = tree2.treeSort(unsortedNums);
Combining Generics and arrays is problematic in Java; check out the article Restrictions on Generics for details.
As to solving the problem, the easiest thing to do would be not using an array but rather a List. So for example:
public List<T> treeSort(List<T> list) {
List<T> result = new ArrayList<T>(list.size());
for (int i = 0; i < list.size(); i++)
if (list.get(i) != null)
result.add(list.get(i));
Iterator<T> it = list.iterator();
int count = 0;
while (it.hasNext())
result.set(count++, it.next());
return result;
}
Mind you, I haven't tested the logic.