java.lang.ClassCastException:[I cannot be cast to java.lang.Integer - java

public class Solution {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int l1=Integer.parseInt(br.readLine());int count=0;
String l2=br.readLine();
String[] a=l2.split(" ");int[] no=new int[l1];
for (int i=0;i<l1;i++) {
no[i]=Integer.parseInt(a[i]);
}
List list=Arrays.asList(no);
Set<Integer> set=new LinkedHashSet<Integer>(list);
***for (int integer : set) {***
count=Math.max(count, Collections.frequency(list, integer));
}
}
}
I get java.lang.ClassCastException:
[I cannot be cast to java.lang.Integer at Solution.main(Solution.java:23) at the highlighted part of the code. What is the reason for this?

You are trying to initialize a set from an array of primitive integers. When you do this
List list=Arrays.asList(no);
since List is untyped, you construct a list of integer arrays; this is definitely not what you are looking for, because you need List<Integer>.
Fortunately, this is very easy to fix: change declaration of no to
Integer[] no=new Integer[l1];
and construct list as follows:
List<Integer> list = Arrays.asList(no);
Everything else should work fine.

Set<Integer> set=new LinkedHashSet<Integer>(list); produce unchecked warnings. This masks that the correct generic type of list is List<int[]>, so set contains not Integers as intended, but arrays of ints. That's what is reported by ClassCastException: int[] (referred as [I) cannot be cast to Integer.
The simplest way to fix this code is to declare no as Integer[], not int[]. In this case, Arrays.asList will return correctly-typed List<Integer>.

Related

Convert generic arraylist to non-generic using Java 8 Stream

I have some old code I'm trying to streamline:
ArrayList arr = (generic arraylist)
int[] newArr = new int[arr.size()];
for(int i=0; i<arr.size(); i++){
newArr[i]=(int)arr.get(i);
}
I want to use the Java Stream API to simplify this. Here is my attempt:
ArrayList arr = (generic arraylist)
List<Integer> = arr.stream().map(m -> (int)m).collect(Collectors.toList());
My understanding is that it would iterate through arr, typecast every object m to an int, and then collect it into a List. But my compiler says that the right-hand-side of the second line returns and Object and not a List. Where am I going wrong?
Per your attempt, it looks like you want to map your ArrayList to an ArrayList<Integer>. The good news is, you don't need to do any of this. The runtime type of ArrayList<Integer> is just ArrayList (this is called type erasure if you want to search for information about it). Only the compiler knows about the parameterized type.
So this code does what you want:
import java.util.ArrayList;
public class Cast {
public static void main(String[] args) {
// This represents the ArrayList of Integer in your existing code
ArrayList raw = new ArrayList(java.util.Arrays.asList(
Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)
));
// You know what it is, so all you need to do is cast
ArrayList<Integer> typed = (ArrayList<Integer>)raw;
// Still works; now recognized as list of integer
for (Integer x : typed) {
System.err.println(x);
}
}
}

Converting a List to an Array in Java

I am a List of Long type and would like to convert it to an array of long type.
However when adding elements to the list, it says it is unable to find method "add(int)"
my code looks like below
package collections;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
public class ListToArray {
private static List<Long> list;
public static void main(String[] args){
list=new ArrayList<Long>();
list.add(121145788);
list.add(1245898);
long[] arr=new long[list.size()];
arr=list.toArray();
}
}
Error I am getting are
Error(16,13): cannot find method add(int).
Error(21,25): incompatible types
Can someone point out where it's going wrong.
As suggested in the comments, you should add L to force the value to be a long:
list.add(121145788L);
list.add(1245898L);
Explanation:
the values you wanted to add are ints, and list is for longs. Adding the L makes the compiler use the number literal as a value of type Long explicitly, and that can be added to the list.
Without it, the numbers are treated as Integers, and those can't be added to a list of type Long, hence
cannot find method add(int)
There is a method add(long), and that's what is used when the L is used.
To convert to an array, you need to do it the old fashioned way:
for (int i = 0; i < arr.length; i++) {
arr[i]=list.get(i);
}
This is because long is a primitive, and Long is a reference type (i.e. it is an Object). Casting from primitives to Objects isn't always easy. In this case, the old fashioned way works well.
First, this is your code but with all the fixes!
private static List<Long> list;
public static void main(String[] args){
list=new ArrayList<Long>();
list.add(121145788L);
list.add(1245898L);
Long[] arr = new Long[list.size()];
list.toArray(arr);
}
And here is some explanation:
you have a list of type Long. When you add() items to the list - compiler expects them to be of type Long, but you are adding literal values (plain numbers like 121145788) so those are treated as integers (type int) and are autoboxed to Integer instead of Long. So add L to treat literals as long and then they are autoboxed into Long. Fine for the compiler :)
list.toArray(arr); this is the correct method to kinda convert a list to an array. Because the method you used returns array of Object and arr you created is not an array of Object.
And again this correct method I used takes T[] as input, so you need to change your arr declaration a bit to make it of type Long instead of an array of primitive type long.
If for some reason you need long[], the easiest way would be:
long[] arr = new long[list.size()];
for (int i=0; i < list.size(); i++) {
arr[i] = list.get(i);
}
Error(16,13): cannot find method add(int), this is because you are passing int instead of a Long value in a list of Long. You should be doing:
list.add(121145788l);
And for the second error follow this.Hope,it helps!
JVM doesn't automatically cast int (short, byte, char) to Long. It's explained on the next link.
Java: Why can't I cast int to Long
Converting List<Long> to long[] is possible and also is answered on SO.
How to convert List<Integer> to int[] in Java?
That's the answers:
using Java 8 streams
long[] arr = list.stream().mapToLong(Long::longValue).toArray();
using Guava
long[] arr = Longs.toArray(list);
using Apache Commons Lang
long[] arr = ArrayUtils.toPrimitive(list.toArray(new Long[0]))

Passing ArrayList to TreeSet constructor

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()));

Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;

The map function simply iterates through the integer array and applies function to it and then adds it to an output array. I'm getting this error and I can't seem to find where it's casting an Object to an Integer. The map function returns an Integer array and is sent to printArray which takes an Integer array. Any ideas?
public static void main(String[] args)
{
Function<Integer,Integer> function = new CalculateSuccessor<Integer,Integer>();
Integer[] integerArray={1,3,4,2,5};
printArray(map(function, integerArray));
}
I've removed the rest of the code because the solution was found to be the <Integer, Integer> after Function.
its because you use generics Function<Integer,Integer> guava is trying to cast the values you pass as to Integer but you actualy pass Object.
I assume that your printArray method expects an Object[]
An Object[] is not an definition of a "super" instance of Integer[] even if Object is a super class of Integer.
Assume this code was valid:
Object[] array = new Integer[10];
then this would also be valid
array[0] = new Car("Mercedes");
But the latter should not be possible. Hence the "inheritance" restriction on arrays.
Same goes for list for example
List<Object> myList = new ArrayList<Integer>();
It will give you a compiler error.

Why is indexOf failing to find the object?

I created an integer list and am trying to return the index of a specific value.
The array is 3,8,2,5,1,4,7,6 and I want to return the indexOf(3), which should be 0.
I've tried the following in the Eclipse Java Scrapbook after importing java.util.*:
int[] A = {3,8,2,5,1,4,7,9};
Arrays.asList(A).indexOf(3)
I have also tried:
int[] A = {3,8,2,5,1,4,7,6};
ArrayList<Integer> l = new ArrayList(Arrays.asList(A));
l.indexOf(3)
Both are returning -1. Why? How to get this to work as expected?
Arrays.asList(A) returns a List<int[]>. This is because it expects an array of objects, not primitive types. Your options include:
use Integer[] instead of int[]
inline the array, and let autoboxing take care of it; Arrays.asList(3,8,2,5,1,4,7,9) will work fine
use Guava's Ints.asList(int...) method to view the primitive array as a List<Integer>. (Disclosure: I contribute to Guava.)
use Guava's Ints.indexOf(int[], int), which works directly on primitive arrays.
It should be Integer[] not int[] in order to make it work.
Integer[] A = {3,8,2,5,1,4,7,9};
final int i = Arrays.asList(A).indexOf(3);
System.out.println("i = " + i); // prints '0'
Do it this way
Integer[] array = {3,8,2,5,1,4,7,9};
List<Integer> list = Arrays.asList(array);
System.out.println(list.indexOf(8));
asList returns static <T> List<T> Where T cannot be primitive (int[]).

Categories