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[]).
Related
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]))
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.
When I do the following,
arrayList1 - contains one element and it is an int[].
arrayList2 - not compiling (Error : The constructor ArrayList<Integer>(List<int[]>) is undefined)
arrayList3 - contains 7 elements and they are Integer objects
Here's the code:
int[] intArray = new int[]{2,3,4,5,6,7,8};
ArrayList arrayList1 = new ArrayList(Arrays.asList(intArray));
ArrayList<Integer> arrayList2 = new ArrayList<Integer>(Arrays.asList(intArray));
Integer[] integerArray = new Integer[]{2,3,4,5,6,7,8};
ArrayList<Integer> arrayList3 = new ArrayList<Integer>(Arrays.asList(integerArray));
Question :
Why doesn't the compiler auto-box the elements in the int[] to Integer and create an ArrayList<Integer>? What is the reason behind this? Is that my stupidity or some other reason?
The difference is int[] is itself an Object, whereas Integer[] is an array of references to Integer object.
Arrays.asList(T...) method takes variable arguments of some type T with no upper bounds. The erasure of that method is Arrays.asList(Object...). That means it will take variable number of arguments of any type that extends from Object.
Since int is not an Object, but a primitive type, so it can't be passed as individual element of T[], whereas int[] is an Object itself, it will go as first element of the T[] array (T... internally is a T[] only). However, Integer[] will be passed as T[], with each reference in Integer[] passed as different argument to T[].
And even if you would argue that compiler should have done the conversion from each element of int[] array to Integer, well that would be too much work for the compiler. First it would need to take each array element, and box it to Integer, then it would need to internally create an Integer[] from those elements. That is really too much. It already has a direct conversion from int[] to Object, which it follows. Although I have always wished Java allowed implicit conversion from int[] to Integer[], that would have made life simpler while working with generics, but again, that's how the language is designed.
Take a simple example:
Object[] array = new Integer[10]; // this is valid conversion
Object[] array2 = new int[10]; // this is not
Object obj = new int[10]; // this is again a valid conversion
So, in your code Arrays.asList(intArray) returns a ArrayList<int[]> and not ArrayList<Integer>. You can't pass it to the ArrayList<Integer>() constructor.
Related:
int[] and Integer[]: What is the difference?
An int[] is not the same as an Integer[].
An array has as associated Class object. The class object for an array of primitive ints is [I. The class object for an array of Integer is [Ljava/lang/Integer.
An array is itself an object, so converting between two objects of the same type is an identity conversion. Converting between two different typed objects isn't - and int[] and Integer[] are definitely different, as evidenced by the bytecode above.
Lastly, bear in mind that autoboxing would only really apply if there was an associated boxing conversion.
Technically it is possible to do it of course. However autoboxing/unboxing of primitive type array to wrapper type array is more than what you expect.
First look into the auto-boxing/unboxing of Java: What it does is simply a syntax sugar to save you typing the primitive wrapper code. e.g.
Integer i = 10;
Compiler knows that it is expecting an Integer, but int present instead. Therefore what the compiler doing is translating your code to:
Integer i = Integer.valueOf(10);
It does similar thing for unboxing: when in situation that it expects int but Integer is present, compiler replace it with varName.intValue()
Back to array. There are two problems we can forsee:
The first problem is, there is no straight-forward way to transform from an int array to an Integer array. You may argue that the compiler can transform
int[] intArray = ....;
Integer[] wrapperArray = intArray ;
to
Integer[] wrapperArray = new Integer[intArray.size()];
for (int i = 0; i < intArray.size(); i++) {
wrapperArray[i] = Integer.valueOf(intArray[i]);
}
but that seems too much for a syntax sugar.
The second big problem is, when you are passing it as a parameter to a method, if autoboxing/unboxing happens for array, instead of reference of original array is passed, you are now passing the reference of a copy of the original array. In case you are changing the content of array in your method, the original array will not be affected. That can bring you lots of surprises.
e.g.
void foo(Integer[] arr) {
arr[0] = 0;
}
// invoking foo in some code:
int[] intArr = new int[]{9,8,7,6};
foo(intArr);
// intArr[0] will still be 9, instead of 0
Because int[] and Integer[] both are objects. First will hold primitive int values, which are not of type Object while second will store references of Integer objects, which are of type Object.
arrayList1 is really a List of size one.
http://ideone.com/w0b1vY
arrayList1.size() = 1
arrayList3.size() = 7
The int[] is being cast to a single Object. That Object cannot be cast to Integer.
I have an Array of primitives, for example for int, int[] foo. It might be a small sized one, or not.
int foo[] = {1,2,3,4,5,6,7,8,9,0};
What is the best way to create an Iterable<Integer> from it?
Iterable<Integer> fooBar = convert(foo);
Notes:
Please do not answer using loops (unless you can give a good explanation on how the compiler do something smart about them?)
Also note that
int a[] = {1,2,3};
List<Integer> l = Arrays.asList(a);
Will not even compile
Type mismatch: cannot convert from List<int[]> to List<Integer>
Also check
Why is an array not assignable to Iterable?
before answering.
Also, if you use some library (e.g., Guava), please explain why this is the Best. ( Because its from Google is not a complete answer :P )
Last, since there seems to be a homework about that, avoid posting homeworkish code.
Integer foo[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
List<Integer> list = Arrays.asList(foo);
// or
Iterable<Integer> iterable = Arrays.asList(foo);
Though you need to use an Integer array (not an int array) for this to work.
For primitives, you can use guava:
Iterable<Integer> fooBar = Ints.asList(foo);
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
<type>jar</type>
</dependency>
For Java8 with lambdas: (Inspired by Jin Kwon's answer)
final int[] arr = { 1, 2, 3 };
final Iterable<Integer> i1 = () -> Arrays.stream(arr).iterator();
final Iterable<Integer> i2 = () -> IntStream.of(arr).iterator();
final Iterable<Integer> i3 = () -> IntStream.of(arr).boxed().iterator();
just my 2 cents:
final int a[] = {1,2,3};
java.lang.Iterable<Integer> aIterable=new Iterable<Integer>() {
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private int pos=0;
public boolean hasNext() {
return a.length>pos;
}
public Integer next() {
return a[pos++];
}
public void remove() {
throw new UnsupportedOperationException("Cannot remove an element of an array.");
}
};
}
};
With Java 8, you can do this.
final int[] arr = {1, 2, 3};
final PrimitiveIterator.OfInt i1 = Arrays.stream(arr).iterator();
final PrimitiveIterator.OfInt i2 = IntStream.of(arr).iterator();
final Iterator<Integer> i3 = IntStream.of(arr).boxed().iterator();
Guava provides the adapter you want as Int.asList(). There is an equivalent for each primitive type in the associated class, e.g., Booleans for boolean, etc.
int foo[] = {1,2,3,4,5,6,7,8,9,0};
Iterable<Integer> fooBar = Ints.asList(foo);
for(Integer i : fooBar) {
System.out.println(i);
}
The suggestions above to use Arrays.asList won't work, even if they compile because you get an Iterator<int[]> rather than Iterator<Integer>. What happens is that rather than creating a list backed by your array, you created a 1-element list of arrays, containing your array.
In Java 8 or later, Iterable is a functional interface returns Iterator.
So you can do this.
static Iterable<Integer> convert(int[] array) {
return () -> Arrays.stream(array).iterator();
}
and
int[] array = {1, 2, 3};
Iterable<Integer> iterable = convert(array);
for (int i : iterable)
System.out.println(i);
output:
1
2
3
I had the same problem and solved it like this:
final YourType[] yourArray = ...;
return new Iterable<YourType>() {
public Iterator<YourType> iterator() {
return Iterators.forArray(yourArray); // Iterators is a Google guava utility
}
}
The iterator itself is a lazy UnmodifiableIterator but that's exactly what I needed.
First of all, I can only agree that Arrays.asList(T...) is clearly the best solution for Wrapper types or arrays with non-primtive datatypes. This method calls a constructor of a simple private static AbstractList implementation in the Arrays class which basically saves the given array reference as field and simulates a list by overriding the needed methods.
If you can choose between a primtive type or a Wrapper type for your array, I would use the Wrapper type for such situations but of course, it's not always useful or required.
There would be only two possibilities you can do:
1) You can create a class with a static method for each primitive datatype array (boolean, byte, short, int, long, char, float, double returning an Iterable<WrapperType>. These methods would use anonymous classes of Iterator (besides Iterable) which are allowed to contain the reference of the comprising method's argument (for example an int[]) as field in order to implement the methods.
-> This approach is performant and saves you memory (except for the memory of the newly created methods, even though, using Arrays.asList() would take memory in the same way)
2) Since arrays don't have methods (as to be read on the side you linked) they can't provide an Iterator instance either. If you really are too lazy to write new classes, you must use an instance of an already existing class that implements Iterable because there is no other way around than instantiating Iterable or a subtype.
The ONLY way to create an existing Collection derivative implementing Iterable is to use a loop (except you use anonymous classes as described above) or you instantiate an Iterable implementing class whose constructor allows a primtive type array (because Object[] doesn't allow arrays with primitive type elements) but as far as I know, the Java API doesn't feature a class like that.The reason for the loop can be explained easily:for each Collection you need Objects and primtive datatypes aren't objects. Objects are much bigger than primitive types so that they require additional data which must be generated for each element of the primitive type array. That means if two ways of three (using Arrays.asList(T...) or using an existing Collection) require an aggregate of objects, you need to create for each primitive value of your int[] array the wrapper object. The third way would use the array as is and use it in an anonymous class as I think it's preferable due to fast performance.
There is also a third strategy using an Object as argument for the method where you want to use the array or Iterable and it would require type checks to figure out which type the argument has, however I wouldn't recommend it at all as you usually need to consider that the Object hasn't always the required type and that you need seperate code for certain cases.
In conclusion, it's the fault of Java's problematic Generic Type system which doesn't allow to use primitive types as generic type which would save a lot of code by using simply Arrays.asList(T...). So you need to program for each primitive type array, you need, such a method (which basically makes no difference to the memory used by a C++ program which would create for each used type argument a seperate method.
You can use IterableOf from Cactoos:
Iterable<String> names = new IterableOf<>(
"Scott Fitzgerald", "Fyodor Dostoyevsky"
);
Then, you can turn it into a list using ListOf:
List<String> names = new ListOf<>(
new IterableOf<>(
"Scott Fitzgerald", "Fyodor Dostoyevsky"
)
);
Or simply this:
List<String> names = new ListOf<>(
"Scott Fitzgerald", "Fyodor Dostoyevsky"
);
While a similar answer has already been sort of posted, I think the reason to use the new PrimitiveIterator.OfInt was not clear. A good solution is to use Java 8 PrimitiveIterator since it's specialized for primitive int types (and avoids the extra boxing/unboxing penalty):
int[] arr = {1,2,3};
// If you use Iterator<Integer> here as type then you can't get the actual benefit of being able to use nextInt() later
PrimitiveIterator.OfInt iterator = Arrays.stream(arr).iterator();
while (iterator.hasNext()) {
System.out.println(iterator.nextInt());
// Use nextInt() instead of next() here to avoid extra boxing penalty
}
Ref: https://doc.bccnsoft.com/docs/jdk8u12-docs/api/java/util/PrimitiveIterator.OfInt.html
In java8 IntSteam stream can be boxed to stream of Integers.
public static Iterable<Integer> toIterable(int[] ints) {
return IntStream.of(ints).boxed().collect(Collectors.toList());
}
I think performance matters based on the size of the array.
I've got a HashSet<Integer> with a bunch of Integers in it. I want to turn it into an array, but calling
hashset.toArray();
returns an Object[]. Is there a better way to cast it to an array of int other than iterating through every element manually? I want to pass the array to
void doSomething(int[] arr)
which won't accept the Object[] array, even if I try casting it like
doSomething((int[]) hashSet.toArray());
You can create an int[] from any Collection<Integer> (including a HashSet<Integer>) using Java 8 streams:
int[] array = coll.stream().mapToInt(Number::intValue).toArray();
The library is still iterating over the collection (or other stream source) on your behalf, of course.
In addition to being concise and having no external library dependencies, streams also let you go parallel if you have a really big collection to copy.
Apache's ArrayUtils has this (it still iterates behind the scenes):
doSomething(ArrayUtils.toPrimitive(hashset.toArray()));
They're always a good place to check for things like this.
You can convert a Set<Integer> to Integer[] even without Apache Utils:
Set<Integer> myset = new HashSet<Integer>();
Integer[] array = myset.toArray(new Integer[0]);
However, if you need int[] you have to iterate over the set.
Try this.
Using java 8.
Set<Integer> set = new HashSet<>();
set.add(43);
set.add(423);
set.add(11);
set.add(44);
set.add(56);
set.add(422);
set.add(34);
int[] arr = set.stream().mapToInt(Integer::intValue).toArray();
Note: This answer is outdated, use Stream.mapToInt(..)
public int[] toInt(Set<Integer> set) {
int[] a = new int[set.size()];
int i = 0;
for (Integer val : set) {
// treat null as 0
a[i++] = val == null ? 0 : val;
}
return a;
}
Now that I wrote the code for you it's not that manual anymore, is it? ;)
You can just use Guava's:
Ints.toArray(Collection<? extends Number> collection)
Nope; you've got to iterate over them. Sorry.
You could also use the toArray(T[] contents) variant of the toArray() method. Create an empty array of ints of the same size as the HashSet, and then pass it to the toArray() method:
Integer[] myarray = new Integer[hashset.size()];
doSomething(hashset.toArray(myarray));
You'd have to change the doSomething() function to accept an Integer[] array instead of int[]. If that is not feasible, you'd have convert the array of values returned by toArray to int[].