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()));
}
Related
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);
I'm trying to convert some python code to java and need to setup a default value of a list. I know the default value, the size of the list and my goal is to setup a default value and then later in my program change them. In python I simply do this(to create 10 items with a value of zero):
list = [0]*10
I am trying to do:
List<Integer> list1 = Arrays.asList(0*10); // it just multiples 0 by 10.
It doest work, I know I can do something like this:
for(int i = 0;i<10;i++)
{
list1.add(0);
}
I was wondering if there was an better way(instead of the for loop)?
Arrays.fill lets you avoid the loop.
Integer[] integers = new Integer[10];
Arrays.fill(integers, 0);
List<Integer> integerList = Arrays.asList(integers);
Collections.nCopies is your friend if you need a list instead of an array:
List<Integer> list = Collections.nCopies(10, 0);
If a mutable list is needed, wrap it:
List<Integer> list = new ArrayList<>(Collections.nCopies(10, 0));
Maybe you just need an array?
int[] array = new int[10];
You need a list if you need to change the size of it dynamically. If you don't need this feature, an array may suit your needs, and it will automatically initialize all the values to 0 for you.
You can try:
List<Integer> list1 = Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
There are 10 zeroes. You need to know the number of elements at the compile time, but you have only one line. If you don't know the number of elements at compile time, then you can use the suggested Arrays.fill() approach.
There's nothing built into the standard libraries, as far as I'm aware. But you can easily write such a method once and call it from wherever you want. For example:
public static <T> List<T> newArrayList(T value, int size) {
List<T> list = new ArrayList<T>(size);
for (int i = 0; i < size; i++) {
list.add(value);
}
return list;
}
If you never want to change the size of the list (i.e. add or remove elements), Mike Samuel's answer is probably more efficient. Also note that if you're using a mutable type, you may not get what you want:
List<StringBuilder> list = newArrayList(new StringBuilder(), 10);
list.get(0).append("Foo");
System.out.println(list.get(5)); // Prints "Foo"
... as each element in the list will be a reference to the same object.
If you are using java 8 or above you can do the following. Here are the required imports:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
Here is the code to get it to work
List<Integer> integers = new ArrayList() {{
IntStream.range(0,5).forEach((i) -> add(0));
}};
The double braces are not a mistake they are required! I hope this helps.
List<Integer> list1 = IntStream.range(0, 10)
.mapToObj(i -> 0)
.collect(Collectors.toList());
In Java, not really. Java is relatively verbose when it comes to this sort of stuff, so there isn't much you can do that is simple, other than a loop like you have.
I would stick with the for loop.
BTW... 0*10 = 0 so just enter in the amount you need instead
ArrayList<Integer> list = new ArrayList<Integer>(10);
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 would like to convert an integer [] [] to a Vector<Vector<Double>>. After much reading, it seems no one has left a searchable post on the web for something of this nature. plenty of int vector to double vector, arraylist to vector, etc. Sadly I haven't found what i am looking for. So..Do any of you folks know an appropriate method for this? I was thinking of converting my int[][] to strings then convert that to vector<vector<Double>>. Opinions? Would something like this be useful, ie. converting my array to object array
Object[] a1d = { "Hello World", new Date(), Calendar.getInstance(), };
// Arrays.asList(Object[]) --> List
List l = Arrays.asList(a1d);
// Vector contstructor takes Collection
// List is a subclass of Collection
Vector v;
v = new Vector(l);
// Or, more simply:
v = new Vector(Arrays.asList(a1d));
Otherwise could you give me a better example that may have less steps? Thanks a Bunch again.
First of all: avoid Vector, it is obsolete; use ArrayList instead (or something simmilar).
Read more here
Secondly, if I had to convert a 2d array to a list of lists, I'd keep it very simple:
List<List<Double>> list = new ArrayList<ArrayList<Double>>();
for(int i=0; i<100; i++) //100 or whatever the size is..
{
List<Double> tmp = new ArrayList<Double>();
tmp = Arrays.asList( ... );
list.add( tmp );
}
I hope I understood your problem right.
Vector is an old class that is not deprecated but shouldn't be used anymore. Use ArrayList instead.
You should use the LIst interface rather than using the concrete Vector class. Program on interfaces, not on implementations.
Moreover, having repeating conversions like this shows a lack of design. Encapsulate your data into usable objects that don't need conversion each time you need a new functionality.
If you really need to do this: use loops:
int[][] array = ...;
List<List<Double>> outer = new Vector<List<Double>>();
for (int[] row : array) {
List<Double> inner = new Vector<Double>();
for (int i : row) {
inner.add(Double.valueOf(i));
}
outer.add(inner);
}
Transforming from int to STring and then from String to Double is wasteful.
A Vector is one dimensional.
You could have a Vector of Vectors to simulate a 2D array:
Vector v = new Vector();
for (int i = 0; i < 100; i++) {
v.add(new Vector());
}
//add something to a Vector
((Vector) v.get(50)).add("Hello, world!");
//get it again
String str = (String) ((Vector) v.get(50)).get(0);
Note: Vector is an old collection that is not recommended to be used
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[].