Java Generic Casting Type Mismatch - java

public class MaxHeap<T extends Comparable<T>> implements Heap<T>{
private T[] heap;
private int lastIndex;
public void main(String[] args){
int i;
T[] arr = {1,3,4,5,2}; //ERROR HERE *******
foo
}
public T[] Heapsort(T[]anArray, int n){
// build initial heap
T[]sortedArray = anArray;
for (int i = n-1; i< 0; i--){
//assert: the tree rooted at index is a semiheap
heapRebuild(anArray, i, n);
//assert: the tree rooted at index is a heap
}
//sort the heap array
int last = n-1;
//invariant: Array[0..last] is a heap,
//Array[last+1..n-1] is sorted
for (int j=1; j<n-1;j++) {
sortedArray[0]=sortedArray[last];
last--;
heapRebuild(anArray, 0, last);
}
return sortedArray;
}
protected void heapRebuild(T[ ] items, int root, int size){
foo
}
}
The error is on the line with "T[arr] = {1,3,4,5,2}"
Eclipse complains that there is a:
"Type mismatch: cannot convert from
int to T"
I've tried to casting nearly everywhere but to no avail.A simple way out would be to not use generics but instead just ints but that's sadly not an option. I've got to find a way to resolve the array of ints {1,3,4,5,2} into an array of T so that the rest of my code will work smoothly.

When you use a generic type, you must resolve all the type parameters, i.e. tell the compiler which concrete types you want to use instead of the placeholder T in your code. As the others already pointed out, a primitive type like int can't be used as a generic type parameter - it must be a reference type, like Integer. So you can rewrite your main method into something like
public static void main(String[] args){
int i = 5;
Integer[] arr = {1,3,4,5,2};
MaxHeap<Integer> maxHeap = new MaxHeap<Integer>();
maxHeap.heapSort(arr, i);
}
Note that it should be static. When you instantiate your class, you have to specify the type parameter Integer as above. Then you can pass it the array to be sorted.
A further note: this loop
for (int i = n-1; i< 0; i--){
...
}
will never execute - the loop condition should be i > 0 instead.

Declare arr as an Integer[] instead of a T[]. There are also a couple of other small errors that I fixed here:
public static void main(String[] args){
int i;
Integer[] arr = {1,3,4,5,2}; //ERROR HERE *******
}
public <T> T[] Heapsort(T[]anArray, int n){
// build initial heap
T[]sortedArray = anArray;
for (int i = n-1; i< 0; i--){
//assert: the tree rooted at index is a semiheap
heapRebuild(anArray, i, n);
//assert: the tree rooted at index is a heap
}
//sort the heap array
int last = n-1;
//invariant: Array[0..last] is a heap,
//Array[last+1..n-1] is sorted
for (int j=1; j<n-1;j++) {
sortedArray[0]=sortedArray[last];
last--;
heapRebuild(anArray, 0, last);
}
return sortedArray;
}
protected void heapRebuild(T[ ] items, int root, int size){
//foo
}

You've already said that T extends Comparable<T>. "int" does not extend Comparable<T> not matter how you cast it.

Erm, ever thought about what would happen if you ran this code in a MaxHeap of, say, String objects?
T does not exist until you actually instantiate the generic class. So, it does not make sense to create an array of T with integers if you don't know what T is.
EDIT: Also, generics in Java only work with reference types, and int is a value type. Try using Integer (int's wrapper class) instead.

Related

How to check whether an array with a specific Index is empty?

I followed the points made in this thread, but I get the error "the operator is undefinded for the argument types[...]"
How can I check whether an array is null / empty?
My code:
public class Test{
private int[] array = new int [5];
public int method(int i) {
for(int s = 0; s <= array.length; s++) {
if( array[s] != null) { //I get the error in here even though the highest upvoted answer in the linked question recommends this solution. I obviously cant check it for 0, because the user input can be 0.
array[s] = i;
} else {
method(i);
}
}
}
}
Thanks!
You are getting this error as int is a primitive type. In your case array[s] returns an int not an Integer. Int can't be a null.
Change your array from int[] to Integer[] if you want to check null.
private Integer[] array = new Integer[5];
You have array of int which is primitive type, primitive types in Java can't be null so compiler gives error when checking if it is null, if you really want it you can use Integer which is wrapper class for int.

Can I swap two int[] using swap function in java?

I created a 2D array of int[]
Now, I want to swap two int[] inside of 2D array
I have this for my code:
swap(values[row][col], values[randomRow][randomCol]);
where values is a 2D array of int[].
so values[int][int] is a int[];
I get an error message like this:
Error: The method swap(int[], int[]) is undefined for the type ShufflePic
How should I fix this?
Thanks a lot!
Java is pass-by-value. You cannot swap values like this.
Instead use this approach :
void swap(int[][] array, int row1, int col1, int row2, int col2) {
int temp = array[row1][col1];
array[row1][col1] = array[row2][col2];
array[row2][col2] = temp;
}
Now you can call swap(...) method to swap the values
swap(values, row, col, randomRow, randomCol);
mybe your method should looks like
swap(int[] arryFirst, int arryFirstRow, int arryFirstCol, int[] arrySec, int arrySecRow, int arrySecCol)
Basically, this finds the indices and swaps according to these indices. Try printing the items in the list after swapping. Of course, this technique could also be implemented for 2D arrays, but I'll leave that as a challenge for you.
public class Test {
static int[] list = {4, 5, 6, 3, 1, 2};
public static void main(String[] args) {
swap(6, 2); // test swap
}
public static void swap(int a, int b) {
int a_index = 0;
int b_index = 0;
for (int i = 0; i < list.length; i++) {
if (list[i] == a) a_index = i;
if (list[i] == b) b_index = i;
}
list[a_index] = b;
list[b_index] = a;
}
}
I created a 2D array of int[]
You did indeed do that, but you probably wanted to create a 2D array of int, not int[].
values[row][col] = 5 //2d int array
values[row][col] = new int[length] //3d int array. Probably not what you intended
Once you fix that, the other answers about passing by value should work for you.
EDIT:
If that's what you want, then this method should work:
public void swapArrays(int[][][] arr, int row1, int col1, int row2, int col2) {
int[] temp = arr[row1][col1];
arr[row1][col1] = arr[row2][col2];
arr[row2][col2] = temp;
}
You would then call this with:
swapArrays(values, row, col, randomRow, randomCol);
The reason you were getting the error is because you hadn't defined a swap function which takes in two arrays. However, even if you had, it wouldn't have functioned properly because of the pass-by-value, pass-by-reference thing. (Google it for more info on that.)
With my proposed method, it will have a reference to the entire array, enabling it to change its values. If you just passed in values[row][col], the method would only see the value stored at that index, but not access to the values array.

Java: array methods

This code supposedly checks an array of integers for 9's and returns it's frequency but the method is not being recognized. Any help please to make this code work.
public static int arrayCount9(int[] nums) {
int count = 0;
for (int i=0; i<nums.length; i++) {
if (nums[i] == 9) {
count++;
}
}
return count;
};
public static void main(String[]args){
System.out.println(arrayCount9({1,2,9}));
}
Change your method call to the following:
System.out.println(arrayCount9(new int[]{1,2,9}));
Alternatively:
int[] a = {1,2,9};
System.out.println(arrayCount9(a));
The shortcut syntax {1,2,9} can only be used when initializing an array type. If you pass this notation to a method, it will not be interpreted it as an array by the compiler.

Java Arrays.binarySearch with compareTo

I need to use Arrays.binarySearch on an array of custom objects. Here is the object:
class Range implements Comparable<Range>{
public int bottom;
public int top;
public Range(int botIn, int topIn) {
this.bottom = botIn;
this.top = topIn;
}
#Override
public int compareTo(Range compareRange) {
int compareQuantity = ((Range) compareRange).bottom;
return this.bottom - compareQuantity;
}}
In my main I first call Arrays.sort(lowerBounds); where lowerBounds is an array of Range elements. This works just fine and sorts them using the compareTo I wrote. Then I call Arrays.binarySearch(lowerBounds, 0) but I get "Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to compareToTest.Range".
What am I doing wrong? Thank you.
Edit: here is main:
public static void main(String[] args)
{
int[] A = {1, 5, 2, 1, 4, 0};
// write your code in Java SE 6
Range[] lowerBounds = new Range[A.length];
for(int i=0; i< A.length; i++)
{
lowerBounds[i] = new Range(i-A[i], i+A[i]);
}
Arrays.sort(lowerBounds);
for(int i=0; i< A.length; i++)
{
System.out.println(lowerBounds[i].bottom);
}
System.out.println(Arrays.binarySearch(lowerBounds, 0));
}
Arrays.binarySearch accepts two parameters - an array to search in, and the object you're looking for. You have supplied an array of Range object and an int (which is autoboxed to an Integer). Naturally, you can't search for an Integer in an array of Ranges.
Instead, you should create the Range object you're looking for. E.g.:
Range r = new Range (0, 0);
Arrays.binarySearch (lowerBounds, r);
Arrays.binarySearch(lowerBounds, 0) is wrong because you are comparing Range Objects.SO you need to pass a Range Object instead of an Integer Object which results in java.lang.ClassCastException: java.lang.Integer cannot be cast to compareToTest.Range"
You need to create a RangeObject and pass it in binarySearch method
Range r = new Range(0,<any integer>)
Arrays.binarySearch (lowerBounds, r);

Creating a new generic type array using Array.newInstance()

For practice, I'm trying to implement the merge sort algorithm but got stuck pretty fast when trying to instantiate a generic type array. I'm not entirely sure if my plan will work out, but right now the interesting part (or frustrating, depending on when you ask me) is the second row in the merge() method. The newInstance() method needs to know what class it should initiate as, but even if arr1.getClass() compiles perfectly fine, it won't work during runtime.
public void mergeSort(T[] arr) {
T[] merged = merge(Arrays.copyOfRange(arr, 0, arr.length/2), Arrays.copyOfRange(arr, arr.length/2+1, arr.length-1));
}
#SuppressWarnings({"unchecked"})
public T[] merge(T[] arr1, T[] arr2) {
// A new array of type T that will contain a merged version of arr1 and arr2
T[] merged = (T[]) Array.newInstance(arr1.getClass(), arr1.length+arr2.length);
int i1 = 0, i2 = 0;
for (int i = 0; i < arr1.length + arr2.length; i++) {
if (arr1[i1].compareTo(arr2[i2]) < 0) {
merged[i] = arr1[i1];
i1++;
} else {
merged[i] = arr2[i2];
i2++;
}
}
return merged;
}
The error message is:
Exception in thread "main" java.lang.ClassCastException: [[Ljava.lang.String; cannot be cast to [Ljava.lang.Comparable;
at sort.SortingAndSearching.merge(SortingAndSearching.java:94)
at sort.SortingAndSearching.mergeSort(SortingAndSearching.java:84)
at sort.SortingAndSearching.main(SortingAndSearching.java:19)
Think I see the issue... When you do Array.newInstance(...), it takes in the component type (in your case, you want it to be String). However, you're handing the array class (arr1 is of type String[], and you're doing arr1.getClass()). Instead, do
arr1.getClass().getComponentType()
to get the String class out of String[]
Per javadoc:
static Object newInstance(Class<?> componentType, int[] dimensions)
componentType - the Class object representing the component type of the new array
I copied and pasted the code you gave and it doesn't even compile. After doing some fixes, I came to this:
public class Test {
public <T extends Comparable> void mergeSort(T[] arr) {
T[] merged = merge(Arrays.copyOfRange(arr, 0, arr.length / 2), Arrays.copyOfRange(arr, arr.length / 2 + 1, arr.length - 1));
}
public <T extends Comparable> T[] merge(T[] arr1, T[] arr2) {
// A new array of type T that will contain a merged version of arr1 and arr2
T[] merged = (T[]) Array.newInstance(arr1.getClass(), arr1.length + arr2.length);
int i1 = 0, i2 = 0;
for(int i = 0; i < arr1.length + arr2.length; i++) {
if(arr1[i1].compareTo(arr2[i2]) < 0) {
merged[i] = arr1[i1];
i1++;
} else {
merged[i] = arr2[i2];
i2++;
}
}
return merged;
}
}
Since you are using the compareTo method, you must tell the compiler that T implements this interface.

Categories

Resources