Convert nested list to 2d array - java

I'm trying to convert a nested list into a 2d array.
List<List<String>> list = new ArrayList<>();
list.add(Arrays.asList("a", "b", "c"));
list.add(Arrays.asList("dd"));
list.add(Arrays.asList("eee", "fff"));
I want to make this a String[][]. I've tried the following:
String[][] array = (String[][]) list.toArray(); // ClassCastException
String[][] array = list.toArray(new String[3][3]); // ArrayStoreException
String[][] array = (String[][]) list.stream() // ClassCastException
.map(sublist -> (String[]) sublist.toArray()).toArray();
Is there a way that works? Note that I won't know the size of the list until runtime, and it may be jagged.

You could do this:
String[][] array = list.stream()
.map(l -> l.stream().toArray(String[]::new))
.toArray(String[][]::new);
It creates a Stream<List<String>> from your list of lists, then from that uses map to replace each of the lists with an array of strings which results in a Stream<String[]>, then finally calls toArray(with a generator function, instead of the no-parameter version) on that to produce the String[][].

There is no simple builtin way to do what you want because your list.toArray() can return only array of elements stored in list which in your case would also be lists.
Simplest solution would be creating two dimensional array and filling it with results of toArray from each of nested lists.
String[][] array = new String[list.size()][];
int i = 0;
for (List<String> nestedList : list) {
array[i++] = nestedList.toArray(new String[0]);
}
(you can shorten this code if you are using Java 8 with streams just like Alex did)

This is the best and most efficient way to convert 2d list to 2d array;
List<List<Integer>> list2d = new ArrayList<>();
Integer[][] array2d;
array2d = list2d.stream().map(x->x.toArray(new Integer[x.size()])).toArray(Integer[][]::new);

Related

Java - Convert/Copy all values of String[] array into ArrayList<BigInteger>

Is it possible to copy and/or convert all values from String[] array into an ArrayList<BigInteger> in one just line?
Like this:
List<String> strings = Arrays.asList(StringArray);
My current source code had no problem but i'm finding a way (if there is) to make it more efficient.
List<BigInteger> Data = new ArrayList<BigInteger>();
for (String current : StringArray) //Gets values from array String[] unsorted
Data.add(new BigInteger(current)); //Each string will be added in the list
My logic to achieve my goal is to iterate through entire array of String[] then get each Strings and add every String into the List<BigInteger>
Use Streams:
List<BigInteger> data = Arrays.stream(StringArray).map(BigInteger::new).collect(Collectors.toList());
With Java 8 you could shortcut :
List<BigInteger> data = Arrays.stream(strings)
.map(BigInteger::new)
.collect(toList());

Casting 2d Array to List of lists in Java

So, this might be a simple question, but I wasn't able to find any easy or elegant way to do this. Converting an array to a list is trivial in Java
Double[] old = new Double[size];
List<Double> cast = Arrays.asList(old);
But I'm dealing with images currently and I would like the ability to extend this functionality to a 2d array without having to iterate through one dimension of the array appending to a list.
Double[][] -> List<List<Double>>
Is basically what I would like to achieve. I have a solution along the lines of:
Double[][] old= new Double[width][height];
List<List<Double>> new= new ArrayList<List<Double>>();
for (int i=0;i<old.length();i++){
new.add(Arrays.asList(old[i]));
}
I would like something better and potentially faster than this.
The only faster way to do this would be with a fancier view; you could do this with Guava like so:
Double[][] array;
List<List<Double>> list = Lists.transform(Arrays.asList(array),
new Function<Double[], List<Double>>() {
#Override public List<Double> apply(Double[] row) {
return Arrays.asList(row);
}
}
}
That returns a view in constant time.
Short of that, you already have the best solution.
(FWIW, if you do end up using Guava, you could use Doubles.asList(double[]) so you could use a primitive double[][] instead of a boxed Double[][].)
As Java8 you do Arrays.stream(array).map(Arrays::asList).collect(Collectors.toList()).
After JAVA 8 stream APIs we can get the list of lists from 2d array in a much faster and cleaner way.
Double[][] old= new Double[width][height];
List<List<Double>> listOfLists = Arrays.stream(Objects.requireNonNull(old)).map(row -> {
return Arrays.asList((row != null) ? row : new Double[0]);
}).collect(Collectors.toList());
Consider matrix as your 2d array then
List<List<Integer>> resList = new ArrayList<>();
for(int[] rows : matrix) {
resList.add(Arrays.stream(rows).boxed().collect(Collectors.toList()));
}

retrieve values from arraylist of hashmap in java?

I've a hashmap as shown below.
indexMap = new HashMap<String, ArrayList<Integer>>();
I could collect values from string like this,
String[] keysProblem2 = (String[]) indexMap.keySet().toArray(new String[0]);
How to collect values from arraylist? I tried doing like this,
Integer [] valuesProblem2 = (Integer[]) indexMap.values().toArray(new Integer[indexMap.size()]);
but was given an error like this,
java.lang.ArrayStoreException: java.lang.String
at java.util.AbstractCollection.toArray(Unknown Source)
indexMap.values() returns a Collection of ArrayList<Integer>s. You can't call .toArray(new Integer[indexMap.size()]) because it's a collection of ArrayList<Integer>, not Integers.
If you want to iterate through all ArrayLists, and create one large Integer[], then you'd have to do something like this:
ArrayList<ArrayList<Integer>> arrays = new ArrayList<ArrayList<Integer>>(indexMap.values());
ArrayList<Integer> allInts = new ArrayList<Integer>();
for(ArrayList<Integer> ints : arrays) {
allInts.addAll(ints);
}
Integer[] valuesProblem2 = (Integer[])allInts.toArray(new Integer[0]);

Convert list to array in Java [duplicate]

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

Java Array and ArrayList

When I try to create an ArrayList myArrayList from an array, using Arrays.asList(myArray), I am not getting the List of elements in myArray. Instead I get list of Array.
The size of myArrayList is 1 . When I try to do myArrayList.toArray(), I am getting a two dimensional array. What to do to get the elements of myArray in a list? Is iterating the only option??
Firstly, the asList method is the right method:
Integer[] myArray = new Integer[3];
List<Integer> myArrayList = Arrays.asList(myArray);
System.out.println(myArrayList.size()); // prints 3, as expected
The problem may be that you are calling the varargs asList method in such a way that java is interpreting your parameter as the first varargs value (and not as an array of values).
Object myArray = new Integer[3];
List<Object> myArrayList = Arrays.asList(myArray);
System.out.println(myArrayList.size()); // prints 1 - java invoked it as an array of Integer[]
To fix this problem, try casting your parameter as Object[] to force the varargs invocation, eg:
Object myArray = new Integer[3];
List<Object> myArrayList = Arrays.asList((Object[]) myArray); // Note cast here
System.out.println(myArrayList.size()); // prints 3, as desired
What is the type of myArray? You cannot use Arrays.asList with an array of primitive type (such as int[]). You need to use loop in that case.
There are different ways by which you can achieve it.3 example of converting array to arraylist and arraylist to array in java might help.
Would this work?
Object[] myArray = new Object[4]; //change this to whatever object you have
ArrayList<Object> list = new ArrayList<Object>();
for (Object thing : myArray) list.add(thing);
Try providing the generic type in the method call. The following gives me a list of 2 String elements.
String[] strings = new String[]{"1", "2"};
List<String> list = Arrays.<String>asList(strings);
System.out.println(list.size());

Categories