I have the below piece of code for swapping.
public static <E> void swap(List<E> list, int i, int j){
E temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
Now when I use List backed by Integer array like below
Integer[] ar = new Integer[]{1,2};
swap(Arrays.asList(ar),1,0);
It works fine and gives output as [2,1]
But I use List backed by int array like below
int[] ar = new int[]{1,2};
swap(Arrays.asList(ar),1,0);
It hrows ArrayIndexOutOfBounds exception. I don't understand why this is happening. List should treat int element as object only. Little help please.
Here is what is happening. Your current code is actually creating a List<Object>, which happens to contain just a single int[], not a list of actual integers:
int[] ar = new int[]{1,2};
List<Object> list = Arrays.asList(ar);
The reason for the ArrayIndexOutOfBounds exception is that the list you pass in to the swap method has only one entry, at index zero.
In any case, it is not possible to use Arrays.asList to directly convert an array of primitives to a list of some boxed type. The first version of your code is correct, and is what you should be using:
Integer[] ar = new Integer[] {1, 2};
swap(Arrays.asList(ar), 1, 0);
Related
I wrote following code and was surprised to see the output:
Integer a = 211;
int b = 211;
int[] array = {210,211,212};
System.out.println(Arrays.asList(array).contains(a));
System.out.println(Arrays.asList(array).contains(b));
Output:
false
false
I found this question and some other questions linked to it and learned that asList method doesn't Autobox stuffs. I checked the returned type in eclipse javadoc preview:
I couldn't quite understand this return type. int[] is an object and not a primitive so its fine. I'm sure that I'm not getting List<Integer> (something which I expected) but I'm not sure how to use the thing which is being returned. My questions are:
1. How exactly do I expect that list methods will work when I'm expecting an List of Integer and getting a List of int[] ?
2. In case of Strings the return type is List of String and not List of String[]. What sort of implementation differences are there?
3. What good is this method for primitives if things are so uncertain?
There are obviously 3 questions here so lets tackle them one by one:
How exactly do I expect that list methods will work when I'm expecting an List of Integer and getting a List of int[] ?
Well, List methods will work exactly as expected, a List<T> is a list of types T. Here T is an int[] so a List<int[]> will contains arrays as each element:
[{1, 2}, {3, 4}, {1, 6}]
So get(i) will return the ith element. In the case of Arrays.asList the List contains a single element, namely the int[] so:
int[] array = {210,211,212};
List<int[]> list = Arrays.asList(array);
Will be
[{210, 211, 212}]
And so
list.get(0)[0] == 210
In case of Strings the return type is List of String and not List of String[]. What sort of implementation differences are there?
String is an Object, not a primitive type. The difference follows from that.
What good is this method for primitives if things are so uncertain?
Things are not uncertain. This method results in defined and predictable behaviour. It's just not very useful for primitives. This is (yet another) side effect of combining Java's type system with generics.
Note with Java 8 the conversion of an int[] to a List<Integer> is very simple:
List<Integer> list = Arrays.stream(array).
boxed().
collect(toList());
You are not getting a Lit or a List (which can't be), you're getting a List of arrays of integer.
So your list does not contain 211, it contains an array that then contains 211.
The array is not "unrolled" into the list, it is added "as is" to a newly created list.
So :
System.out.println(Arrays.asList(array).contains(array)); // Will return true
System.out.println(Arrays.asList(a).contains(a)); // Will return true
It is because Arrays.asList() is a variadic generic function. Change this,
int[] array = {210,211,212};
to
Integer[] array = { 210, 211, 212 };
And the output will be true and true.
Arrays.asList takes objects as params. Since int[] is an object, you get the List.
If you want a list of integers you should do Arrays.asList(211,212,213).
int[] array = {210,211,212};
Arrays.asList(array)
is equal to
List<int[]> asList = Arrays.asList(array);
Change
int[] array = {210,211,212}; to Integer[] array = {210,211,212}; and it will work.
and its equals to List<Integer> asList = Arrays.asList(array);
Good day guys, I am trying to sort here using an array, Check my codes
public int[] Sort(int[] arr) {
int[] value = arr;
int min, temp, out;
for (out = 0; out < value.length - 1; out++) {
for (min = out + 1; min < value.length; min++) {
if(value[out] > value[min]){
temp = value[min];
value[min] = value[out];
value[out] = temp;
}
}
}
return value;
}
The problem here is I pass the array 'arr' value to the array 'value' and sort the 'value' array then the output is what i expect, he sorted the number, but the problem is, when i tried to return the 'arr' array it also return a sorted value even though i didn't tried to sort it .. is it a bug or just my ugly coding ?
When you make the assignment int[] value = arr, you give value the same reference as arr. This means that assigning, for example, value[1] will affect the original array. If you want to return a new sorted array without affecting the original one, then you can try making a copy of it:
public int[] Sort(int[] arr) {
int[] value = new int[arr.length];
System.arraycopy(arr, 0, value, 0, arr.length);
// ...
return value;
}
Your variables arr and value both point to the same array.
Apparently you thought your sorting manipulations were applied to a second array. But, no, you were changing the original array.
Learn about reference variables. The two variables are not an array themselves, they are a pointer to an array that lives elsewhere in memory. So there are three “things” in play here. One reference variable, another reference variable, and an array. All three are distinct from one another.
When these reference variables go out of scope or get assigned to another object, so no more reference variables point to the array object, then the array object becomes a candidate for garbage collection.
Seems that you want to copy the array to another array. Stack Overflow has many Questions and Answers on the topic of copying an array in Java for you to study. Like this one.
Here is another approach, You'd clone the array and sort
int[] value = arr.clone();
any operation on the cloned array wont affect the original array.
Ex
int[] arr = { 1, 4, 3 };
int[] a = arr.clone();
a[2] = 5;
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(a));
output
[1, 4, 3]
[1, 4, 5]
I have values that I'd like to add into an ArrayList to keep track of what numbers have shown up.
The values are integers so I created an ArrayList;
ArrayList<Integer[]> list = new ArrayList<>();
int x = 5
list.add(x);
But I'm unable to add anything to the ArrayList using this method.
It works if I use Strings for the array list. Would I have to make it a String array and then somehow convert the array to integers?
EDIT: I have another question. I'd like the list to only hold 3 values. How would I do so?
List of Integer.
List<Integer> list = new ArrayList<>();
int x = 5;
list.add(x);
You are trying to add an integer into an ArrayList that takes an array of integers Integer[]. It should be
ArrayList<Integer> list = new ArrayList<>();
or better
List<Integer> list = new ArrayList<>();
you are not creating an arraylist for integers, but you are trying to create an arraylist for arrays of integers.
so if you want your code to work just put.
List<Integer> list = new ArrayList<>();
int x = 5;
list.add(x);
you should not use Integer[] array inside the list as arraylist itself is a kind of array. Just leave the [] and it should work
Actually what u did is also not wrong your declaration is right . With your declaration JVM will create a ArrayList of integer arrays i.e each entry in arraylist correspond to an integer array hence your add function should pass a integer array as a parameter.
For Ex:
list.add(new Integer[3]);
In this way first entry of ArrayList is an integer array which can hold at max 3 values.
The [] makes no sense in the moment of making an ArrayList of Integers because I imagine you just want to add Integer values.
Just use
List<Integer> list = new ArrayList<>();
to create the ArrayList and it will work.
Here there are two different concepts that are merged togather in your question.
First : Add Integer array into List. Code is as follows.
List<Integer[]> list = new ArrayList<>();
Integer[] intArray1 = new Integer[] {2, 4};
Integer[] intArray2 = new Integer[] {2, 5};
Integer[] intArray3 = new Integer[] {3, 3};
Collections.addAll(list, intArray1, intArray2, intArray3);
Second : Add integer value in list.
List<Integer> list = new ArrayList<>();
int x = 5
list.add(x);
How about creating an ArrayList of a set amount of Integers?
The below method returns an ArrayList of a set amount of Integers.
public static ArrayList<Integer> createRandomList(int sizeParameter)
{
// An ArrayList that method returns
ArrayList<Integer> setIntegerList = new ArrayList<Integer>(sizeParameter);
// Random Object helper
Random randomHelper = new Random();
for (int x = 0; x < sizeParameter; x++)
{
setIntegerList.add(randomHelper.nextInt());
} // End of the for loop
return setIntegerList;
}
I have an array of int:
int[] a = {1, 2, 3};
I need a typed set from it:
Set<Integer> s;
If I do the following:
s = new HashSet(Arrays.asList(a));
it, of course, thinks I mean:
List<int[]>
whereas I meant:
List<Integer>
This is because int is a primitive. If I had used String, all would work:
Set<String> s = new HashSet<String>(
Arrays.asList(new String[] { "1", "2", "3" }));
How to easily, correctly and succinctly go from:
A) int[] a...
to
B) Integer[] a ...
Thanks!
Using Stream:
// int[] nums = {1,2,3,4,5}
Set<Integer> set = Arrays.stream(nums).boxed().collect(Collectors.toSet())
The question asks two separate questions: converting int[] to Integer[] and creating a HashSet<Integer> from an int[]. Both are easy to do with Java 8 streams:
int[] array = ...
Integer[] boxedArray = IntStream.of(array).boxed().toArray(Integer[]::new);
Set<Integer> set = IntStream.of(array).boxed().collect(Collectors.toSet());
//or if you need a HashSet specifically
HashSet<Integer> hashset = IntStream.of(array).boxed()
.collect(Collectors.toCollection(HashSet::new));
Some further explanation. The asList method has this signature
public static <T> List<T> asList(T... a)
So if you do this:
List<Integer> list = Arrays.asList(1, 2, 3, 4)
or this:
List<Integer> list = Arrays.asList(new Integer[] { 1, 2, 3, 4 })
In these cases, I believe java is able to infer that you want a List back, so it fills in the type parameter, which means it expects Integer parameters to the method call. Since it's able to autobox the values from int to Integer, it's fine.
However, this will not work
List<Integer> list = Arrays.asList(new int[] { 1, 2, 3, 4} )
because primitive to wrapper coercion (ie. int[] to Integer[]) is not built into the language (not sure why they didn't do this, but they didn't).
As a result, each primitive type would have to be handled as it's own overloaded method, which is what the commons package does. ie.
public static List<Integer> asList(int i...);
Or you could easly use Guava to convert int[] to List<Integer>:
Ints.asList(int...)
asList
public static List<Integer> asList(int... backingArray)
Returns a fixed-size list backed by the specified array, similar to Arrays.asList(Object[]). The list supports List.set(int, Object), but any attempt to set a value to null will result in a NullPointerException.
The returned list maintains the values, but not the identities, of Integer objects written to or read from it. For example, whether list.get(0) == list.get(0) is true for the returned list is unspecified.
You can use ArrayUtils in Apache Commons:
int[] intArray = { 1, 2, 3 };
Integer[] integerArray = ArrayUtils.toObject(intArray);
Another option would be to use a primitive set from Eclipse Collections. You can easily convert an int[] to a MutableIntSet to a Set<Integer> or Integer[] as shown below, or you can use the MutableIntSet as is which will be much more memory efficient and performant.
int[] a = {1, 2, 3};
MutableIntSet intSet = IntSets.mutable.with(a);
Set<Integer> integerSet = intSet.collect(i -> i); // auto-boxing
Integer[] integerArray = integerSet.toArray(new Integer[]{});
If you want to go directly from the int array to the Integer array and preserve order, then this will work.
Integer[] integers =
IntLists.mutable.with(a).collect(i -> i).toArray(new Integer[]{});
Note: I am a committer for Eclipse Collections
Just add elements from array to Set with the below snippet
public class RemoveDuplicateElements {
public static void main(String args[]){
int array[] = {0,1,2,3,4,5,6,7,8,9,1,2,3,4,5};
Set <Integer> abc = new HashSet <Integer>();
for (Integer t:array){
abc.add(t);
}
System.out.println("sampleSet"+abc);
}
}
No need for looping :
Just you will convert the array to a List
Then converting this List to a hash set.
Ex:
List list = Arrays.asList(your_array);
Set set = new HashSet<>(list);
This worked perfect for me .
This question already has answers here:
Converting 'ArrayList<String> to 'String[]' in Java
(17 answers)
Closed 4 years ago.
How can I convert a List to an Array in Java?
Check the code below:
ArrayList<Tienda> tiendas;
List<Tienda> tiendasList;
tiendas = new ArrayList<Tienda>();
Resources res = this.getBaseContext().getResources();
XMLParser saxparser = new XMLParser(marca,res);
tiendasList = saxparser.parse(marca,res);
tiendas = tiendasList.toArray();
this.adaptador = new adaptadorMarca(this, R.layout.filamarca, tiendas);
setListAdapter(this.adaptador);
I need to populate the array tiendas with the values of tiendasList.
Either:
Foo[] array = list.toArray(new Foo[0]);
or:
Foo[] array = new Foo[list.size()];
list.toArray(array); // fill the array
Note that this works only for arrays of reference types. For arrays of primitive types, use the traditional way:
List<Integer> list = ...;
int[] array = new int[list.size()];
for(int i = 0; i < list.size(); i++) array[i] = list.get(i);
Update:
It is recommended now to use list.toArray(new Foo[0]);, not list.toArray(new Foo[list.size()]);.
From JetBrains Intellij Idea inspection:
There are two styles to convert a collection to an array: either using
a pre-sized array (like c.toArray(new String[c.size()])) or
using an empty array (like c.toArray(new String[0]). In
older Java versions using pre-sized array was recommended, as the
reflection call which is necessary to create an array of proper size
was quite slow. However since late updates of OpenJDK 6 this call
was intrinsified, making the performance of the empty array version
the same and sometimes even better, compared to the pre-sized
version. Also passing pre-sized array is dangerous for a concurrent or
synchronized collection as a data race is possible between the
size and toArray call which may result in extra nulls
at the end of the array, if the collection was concurrently shrunk
during the operation. This inspection allows to follow the
uniform style: either using an empty array (which is recommended in
modern Java) or using a pre-sized array (which might be faster in
older Java versions or non-HotSpot based JVMs).
An alternative in Java 8:
String[] strings = list.stream().toArray(String[]::new);
Since Java 11:
String[] strings = list.toArray(String[]::new);
I think this is the simplest way:
Foo[] array = list.toArray(new Foo[0]);
Best thing I came up without Java 8 was:
public static <T> T[] toArray(List<T> list, Class<T> objectClass) {
if (list == null) {
return null;
}
T[] listAsArray = (T[]) Array.newInstance(objectClass, list.size());
list.toArray(listAsArray);
return listAsArray;
}
If anyone has a better way to do this, please share :)
I came across this code snippet that solves it.
//Creating a sample ArrayList
List<Long> list = new ArrayList<Long>();
//Adding some long type values
list.add(100l);
list.add(200l);
list.add(300l);
//Converting the ArrayList to a Long
Long[] array = (Long[]) list.toArray(new Long[list.size()]);
//Printing the results
System.out.println(array[0] + " " + array[1] + " " + array[2]);
The conversion works as follows:
It creates a new Long array, with the size of the original list
It converts the original ArrayList to an array using the newly created one
It casts that array into a Long array (Long[]), which I appropriately named 'array'
This is works. Kind of.
public static Object[] toArray(List<?> a) {
Object[] arr = new Object[a.size()];
for (int i = 0; i < a.size(); i++)
arr[i] = a.get(i);
return arr;
}
Then the main method.
public static void main(String[] args) {
List<String> list = new ArrayList<String>() {{
add("hello");
add("world");
}};
Object[] arr = toArray(list);
System.out.println(arr[0]);
}
For ArrayList the following works:
ArrayList<Foo> list = new ArrayList<Foo>();
//... add values
Foo[] resultArray = new Foo[list.size()];
resultArray = list.toArray(resultArray);
Example taken from this page: http://www.java-examples.com/copy-all-elements-java-arraylist-object-array-example
import java.util.ArrayList;
public class CopyElementsOfArrayListToArrayExample {
public static void main(String[] args) {
//create an ArrayList object
ArrayList arrayList = new ArrayList();
//Add elements to ArrayList
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
arrayList.add("4");
arrayList.add("5");
/*
To copy all elements of java ArrayList object into array use
Object[] toArray() method.
*/
Object[] objArray = arrayList.toArray();
//display contents of Object array
System.out.println("ArrayList elements are copied into an Array.
Now Array Contains..");
for(int index=0; index < objArray.length ; index++)
System.out.println(objArray[index]);
}
}
/*
Output would be
ArrayList elements are copied into an Array. Now Array Contains..
1
2
3
4
5
You can use toArray() api as follows,
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("ListItem1");
stringList.add("ListItem2");
String[] stringArray = new String[stringList.size()];
stringArray = stringList.toArray(stringList);
Values from the array are,
for(String value : stringList)
{
System.out.println(value);
}
This (Ondrej's answer):
Foo[] array = list.toArray(new Foo[0]);
Is the most common idiom I see. Those who are suggesting that you use the actual list size instead of "0" are misunderstanding what's happening here. The toArray call does not care about the size or contents of the given array - it only needs its type. It would have been better if it took an actual Type in which case "Foo.class" would have been a lot clearer. Yes, this idiom generates a dummy object, but including the list size just means that you generate a larger dummy object. Again, the object is not used in any way; it's only the type that's needed.
Try this:
List list = new ArrayList();
list.add("Apple");
list.add("Banana");
Object[] ol = list.toArray();