I want to know if it is safe/advisable to convert from ArrayList to Array?
I have a text file with each line a string:
1236
1233
4566
4568
....
I want to read them into array list and then i convert it to Array. Is it advisable/legal to do that?
thanks
Yes it is safe to convert an ArrayList to an Array. Whether it is a good idea depends on your intended use. Do you need the operations that ArrayList provides? If so, keep it an ArrayList. Else convert away!
ArrayList<Integer> foo = new ArrayList<Integer>();
foo.add(1);
foo.add(1);
foo.add(2);
foo.add(3);
foo.add(5);
Integer[] bar = foo.toArray(new Integer[foo.size()]);
System.out.println("bar.length = " + bar.length);
outputs
bar.length = 5
This is the best way (IMHO).
List<String> myArrayList = new ArrayList<String>();
//.....
String[] myArray = myArrayList.toArray(new String[myArrayList.size()]);
This code works also:
String[] myArray = myArrayList.toArray(new String[0]);
But it less effective: the string array is created twice: first time zero-length array is created, then the real-size array is created, filled and returned. So, if since you know the needed size (from list.size()) you should create array that is big enough to put all elements. In this case it is not re-allocated.
ArrayList<String> myArrayList = new ArrayList<String>();
...
String[] myArray = myArrayList.toArray(new String[0]);
Whether it's a "good idea" would really be dependent on your use case.
assuming v is a ArrayList:
String[] x = (String[]) v.toArray(new String[0]);
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.
You can 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).
This is the recommended usage for newer Java ( >Java 6)
String[] myArray = myArrayList.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).
Most answers work as accepted. But since Java 11, there's another way to use toArray() method using method reference operator or double colon operation (::).
Here's an example:
ArrayList<String> list = new ArrayList<>();
// ... add strings to list
// Since java 11
String[] strArray = list.toArray(String[]::new);
// before java 11, as specified in the official documentation.
strArray = list.toArray(new String[0]);
The Collection interface includes the toArray() method to convert a new collection into an array. There are two forms of this method. The no argument version will return the elements of the collection in an Object array: public Object[ ] toArray(). The returned array cannot cast to any other data type. This is the simplest version. The second version requires you to pass in the data type of the array you’d like to return: public Object [ ] toArray(Object type[ ]).
public static void main(String[] args) {
List<String> l=new ArrayList<String>();
l.add("A");
l.add("B");
l.add("C");
Object arr[]=l.toArray();
for(Object a:arr)
{
String str=(String)a;
System.out.println(str);
}
}
for reference, refer this link http://techno-terminal.blogspot.in/2015/11/how-to-obtain-array-from-arraylist.html
One approach would be to add the Second for Loop where the printing is being done inside the first for loop. Like this:
static String[] SENTENCE;
public static void main(String []args) throws Exception{
Scanner sentence = new Scanner(new File("assets/blah.txt"));
ArrayList<String> sentenceList = new ArrayList<String>();
while (sentence.hasNextLine())
{
sentenceList.add(sentence.nextLine());
}
sentence.close();
String[] sentenceArray = sentenceList.toArray(new String[sentenceList.size()]);
// System.out.println(sentenceArray.length);
for (int r=0;r<sentenceArray.length;r++)
{
SENTENCE = sentenceArray[r].split("(?<=[.!?])\\s*"); //split sentences and store in array
for (int i=0;i<SENTENCE.length;i++)
{
System.out.println("Sentence " + (i+1) + ": " + SENTENCE[i]);
}
}
}
ArrayList<String> a = new ArrayList<String>();
a.add( "test" );
#SuppressWarnings( "unused")
Object[] array = a.toArray();
It depends on what you want to achieve if you need to manipulate the array later it would cost more effort than keeping the string in the ArrayList. You have also random access with an ArrayList by list.get( index );
I usually use this method.
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
int[] arr = list.stream().mapToInt(i -> i).toArray();
System.out.println(Arrays.toString(arr)); // [1, 2, 3]
}
Related
Is there an immutable alternative to the primitive arrays in Java? Making a primitive array final doesn't actually prevent one from doing something like
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
I want the elements of the array to be unchangeable.
Not with primitive arrays. You'll need to use a List or some other data structure:
List<Integer> items = Collections.unmodifiableList(Arrays.asList(0,1,2,3));
My recommendation is to not use an array or an unmodifiableList but to use Guava's ImmutableList, which exists for this purpose.
ImmutableList<Integer> values = ImmutableList.of(0, 1, 2, 3);
As others have noted, you can't have immutable arrays in Java.
If you absolutely need a method that returns an array that doesn't influence the original array, then you'd need to clone the array each time:
public int[] getFooArray() {
return fooArray == null ? null : fooArray.clone();
}
Obviously this is rather expensive (as you'll create a full copy each time you call the getter), but if you can't change the interface (to use a List for example) and can't risk the client changing your internals, then it may be necessary.
This technique is called making a defensive copy.
There is one way to make an immutable array in Java:
final String[] IMMUTABLE = new String[0];
Arrays with 0 elements (obviously) cannot be mutated.
This can actually come in handy if you are using the List.toArray method to convert a List to an array. Since even an empty array takes up some memory, you can save that memory allocation by creating a constant empty array, and always passing it to the toArray method. That method will allocate a new array if the array you pass doesn't have enough space, but if it does (the list is empty), it will return the array you passed, allowing you to reuse that array any time you call toArray on an empty List.
final static String[] EMPTY_STRING_ARRAY = new String[0];
List<String> emptyList = new ArrayList<String>();
return emptyList.toArray(EMPTY_STRING_ARRAY); // returns EMPTY_STRING_ARRAY
As of Java 9 you can use List.of(...), JavaDoc.
This method returns an immutable List and is very efficient.
Another one answer
static class ImmutableArray<T> {
private final T[] array;
private ImmutableArray(T[] a){
array = Arrays.copyOf(a, a.length);
}
public static <T> ImmutableArray<T> from(T[] a){
return new ImmutableArray<T>(a);
}
public T get(int index){
return array[index];
}
}
{
final ImmutableArray<String> sample = ImmutableArray.from(new String[]{"a", "b", "c"});
}
Since Guava 22, from package com.google.common.primitives you can use three new classes, which have a lower memory footprint compared to ImmutableList.
ImmutableIntArray
ImmutableLongArray
ImmutableDoubleArray
They also have a builder. Example:
int size = 2;
ImmutableLongArray longArray = ImmutableLongArray.builder(size)
.add(1L)
.add(2L)
.build();
or, if the size is known at compile-time:
ImmutableLongArray longArray = ImmutableLongArray.of(1L, 2L);
This is another way of getting an immutable view of an array for Java primitives.
If you need (for performance reason or to save memory) native 'int' instead of 'java.lang.Integer', then you would probably need to write your own wrapper class. There are various IntArray implementations on the net, but none (I found) was immutable: Koders IntArray, Lucene IntArray. There are probably others.
The of(E... elements) method in Java9 can be used to create immutable list using just a line:
List<Integer> items = List.of(1,2,3,4,5);
The above method returns an immutable list containing an arbitrary number of elements. And adding any integer to this list would result in java.lang.UnsupportedOperationExceptionexception. This method also accepts a single array as an argument.
String[] array = ... ;
List<String[]> list = List.<String[]>of(array);
No, this is not possible. However, one could do something like this:
List<Integer> temp = new ArrayList<Integer>();
temp.add(Integer.valueOf(0));
temp.add(Integer.valueOf(2));
temp.add(Integer.valueOf(3));
temp.add(Integer.valueOf(4));
List<Integer> immutable = Collections.unmodifiableList(temp);
This requires using wrappers, and is a List, not an array, but is the closest you will get.
In some situations, it will be lighter weight to use this static method from Google Guava library: List<Integer> Ints.asList(int... backingArray)
Examples:
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
If you want to avoid both mutability and boxing, there is no way out of the box. But you can create a class which holds primitive array inside and provides read-only access to elements via method(s).
Implement java.util.function.IntUnaryOperator:
class ImmutableArray implements IntUnaryOperator {
private final int[] array;
ImmutableArray(int[] array) {
this.array = Arrays.copyOf(array, array.length);
}
#Override
public int applyAsInt(int index) {
return array[index];
}
}
Access the array: array[i] becomes immutableArray.applyAsInt(i).
I benchmarked primitive for loop retrieval with a modulus operation with 100_000_000 elements. The above PrimitiveArray took ~220ms; there was no significant difference with a primitive array. The same op on ArrayList took 480 ms, and the loading process took 21 seconds, depleted my heap space first try, and I had to increase this setting on the JVM. Loading of PrimitiveArray had taken 2 seconds.
iteration
if you want to iterate, implement Iterable and provide
public java.util.PrimitiveIterator.OfInt iterator() { return Arrays.stream(array).iterator(); }
This provides access to int nextInt method.
From PrimitiveIterator you also get method forEachRemaining(PrimitiveConsumer) which is helpful to replace an existing enhanced for loop.
Iterating manually with PrimitiveIterator.OfInt yielded performance of ~300ms.
While it's true that Collections.unmodifiableList() works, sometimes you may have a large library having methods already defined to return arrays (e.g. String[]).
To prevent breaking them, you can actually define auxiliary arrays that will store the values:
public class Test {
private final String[] original;
private final String[] auxiliary;
/** constructor */
public Test(String[] _values) {
original = new String[_values.length];
// Pre-allocated array.
auxiliary = new String[_values.length];
System.arraycopy(_values, 0, original, 0, _values.length);
}
/** Get array values. */
public String[] getValues() {
// No need to call clone() - we pre-allocated auxiliary.
System.arraycopy(original, 0, auxiliary, 0, original.length);
return auxiliary;
}
}
To test:
Test test = new Test(new String[]{"a", "b", "C"});
System.out.println(Arrays.asList(test.getValues()));
String[] values = test.getValues();
values[0] = "foobar";
// At this point, "foobar" exist in "auxiliary" but since we are
// copying "original" to "auxiliary" for each call, the next line
// will print the original values "a", "b", "c".
System.out.println(Arrays.asList(test.getValues()));
Not perfect, but at least you have "pseudo immutable arrays" (from the class perspective) and this will not break related code.
Well.. arrays are useful to pass as constants (if they were) as variants parameters.
I'm developing for the Android platform and, to simplify the question, I'm using pseudo-names for the entities.
I have an object array stuff[] of the class StuffClass[].
StuffClass stuff[]={
new StuffClass(Argument, argument, argument),
new StuffClass(argument, argument, argument)
};
I have an activity returning a result of three arguments that I want to then use to add a new object to stuff[]. I've done so as follows:
stuff[stuff.length]=new StuffClass(argument, argument, argument);
and I get ArrayOutOfBounds (Figured that would happen).
So how might I go about creating a new object in the stuff[] array?
Arrays are static you can't change size without creating a new one before. Instead of that you can use a dynamic data structure such as an ArrayList
Example:
List<MyType> objects = new ArrayList<>();
objects.add(new MyType());
Here you forget about array size.
Array in Java is little bit special, it's length is fixed when it's initialized, you can not extend it later on.
What you can do is to create a new array, and use System.arraycopy to generate a new array, here's the sample code:
String[] arr1 = new String[]{"a", "b"};
String[] arr2 = new String[3];
System.arraycopy(arr1, 0, arr2, 0, 2);
arr2[2] = "c";
You cannot increase the size of an existing array. Once it's created, the size of the array is fixed.
You will need to create another bigger array and copy the items from the old array to the new array.
A better alternative is to use an ArrayList. When you add items to an ArrayList, the capacity will grow behind the scenes if needed; you don't have to worry about increasing the size.
you can use the ArrayList to do this
arraylist.add(object);
in java arrays are fixed length. you need to initialise them with the desired length.
Consider using a Collection such as ArrayList which will handle everything for you.
List<StuffClass> myList = new ArrayList<>();
myList.add(...);
Lists support similar behaviour to arrays ie:
myList.set(i, elem);
myArray[i] = elem;
elem = myList.get(i);
elem = myArray[i];
len = myList.size();
len = myArray.length;
You can then convert the list to an array.
StuffClass[] myArray = myList.toArray(new StuffClass[myList.size()]);
If you don't want to use lists consider using System.arrayCopy to create a new array with more elements.
read here for a good description.
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();
I need to get a String[] out of a Set<String>, but I don't know how to do it. The following fails:
Map<String, ?> myMap = gpxlist.getAll();
Set<String> myset = myMap.keySet();
String[] GPXFILES1 = (String[]) myset.toArray(); // Here it fails.
How can I fix it so that it works?
Use the Set#toArray(IntFunction<T[]>) method taking an IntFunction as generator.
String[] GPXFILES1 = myset.toArray(String[]::new);
If you're not on Java 11 yet, then use the Set#toArray(T[]) method taking a typed array argument of the same size.
String[] GPXFILES1 = myset.toArray(new String[myset.size()]);
While still not on Java 11, and you can't guarantee that myset is unmodifiable at the moment of conversion to array, then better specify an empty typed array.
String[] GPXFILES1 = myset.toArray(new String[0]);
Java 11
The new default toArray method in Collection interface allows the elements of the collection to be transferred to a newly created array of the desired runtime type. It takes IntFunction<T[]> generator as argument and can be used as:
String[] array = set.toArray(String[]::new);
There is already a similar method Collection.toArray(T[]) and this addition means we no longer be able to pass null as argument because in that case reference to the method would be ambiguous. But it is still okay since both methods throw a NPE anyways.
Java 8
In Java 8 we can use streams API:
String[] array = set.stream().toArray(String[]::new);
We can also make use of the overloaded version of toArray() which takes IntFunction<A[]> generator as:
String[] array = set.stream().toArray(n -> new String[n]);
The purpose of the generator function here is to take an integer (size of desired array) and produce an array of desired size. I personally prefer the former approach using method reference than the later one using lambda expression.
Use toArray(T[] a) method:
String[] array = set.toArray(new String[0]);
Guava style:
Set<String> myset = myMap.keySet();
FluentIterable.from(mySet).toArray(String.class);
more info: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/FluentIterable.html
In Java 11 we can use Collection.toArray(generator) method. The following code will create a new array of String:
Set<String> set = Set.of("one", "two", "three");
String[] array = set.toArray(String[]::new)
See: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collection.html#toArray(java.util.function.IntFunction)
Set<String> stringSet= new HashSet<>();
String[] s = (String[])stringSet.toArray();
I was facing the same situation.
I begin by declaring the structures I need:
Set<String> myKeysInSet = null;
String[] myArrayOfString = null;
In my case, I have a JSON object and I need all the keys in this JSON to be stored in an array of strings. Using the GSON library, I use JSON.keySet() to get the keys and move to my Set :
myKeysInSet = json_any.keySet();
With this, I have a Set structure with all the keys, as I needed it. So I just need to the values to my Array of Strings. See the code below:
myArrayOfString = myKeysInSet.toArray(new String[myKeysInSet.size()]);
This was my first answer in StackOverflow.
Sorry for any error :D
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[].