In my project I have a List that contains Lists of Strings (List<List<String>>) and now I have to convert this List into an array of String arrays (String[][]).
If I had a single List<String> (for example myList) then I could do this to convert to String[]:
String[] myArray = new String[myList.size()];
myArray = myList.toArray(myArray);
But in this case I have lots of List of String inside a List (of List of Strings).
How can I do this? I've spent lots of time but I didn't find a solution..
I wrote a generic utility method few days back for my own usage, which converts a List<List<T>> to T[][]. Here's the method. You can use it for your purpose:
public static <T> T[][] multiListToArray(final List<List<T>> listOfList,
final Class<T> classz) {
final T[][] array = (T[][]) Array.newInstance(classz, listOfList.size(), 0);
for (int i = 0; i < listOfList.size(); i++) {
array[i] = listOfList.get(i).toArray((T[]) Array.newInstance(classz, listOfList.get(i).size()));
}
return array;
}
There I've created the array using Array#newInstance() method, since you cannot create an array of type parameter T directly.
Since we're creating a 2-D array, and we don't yet know how many columns you will be having, I've given the column size as 0 initially. Anyways, the code is initializing each row with a new array inside the for loop. So, you don't need to worry about that.
This line:
array[i] = listOfList.get(i).toArray((T[]) Array.newInstance(classz, listOfList.get(i).size()));
uses the List#toArray(T[]) method to convert the inner list to an array, as you already did. I'm just passing an array as a parameter to the method so that the return value which I get is T[], which I can directly assign to the current row - array[i].
Now you can use this method as:
String[][] arr = multiListToArray(yourList, String.class);
Thanks to #arshaji, you can modify the generic method to pass the uninitialized array as 2nd parameter, instead of Class<T>:
public static <T> void multiListToArray(final List<List<T>> listOfList,
final T[][] arr) {
for (int i = 0; i < listOfList.size(); ++i) {
arr[i] = listOfList.get(i).toArray(arr[i]);
}
}
But then, you have to pass the array to this method like this:
List<List<String>> list = new ArrayList<>();
// Initialize list
String[][] arr = new String[list.size()][0];
multiListToArray(list, arr);
Note that, since now we are passing the array as argument, you no longer need to return it from your method. The modification done in the array will be reflected to the array in the calling code.
String[][] myArray = new String[myList.size()][];
for (int i = 0; i < myList.size(); i++) {
List<String> row = myList.get(i);
myArray[i] = row.toArray(new String[row.size()]);
}
Here is one way
List<List<String>> list = new ArrayList<List<String>>();
String[][] array = new String[list.size()][];
int counter1 = 0;
for(List<String> outterList : list)
{
array[counter1] = new String[outterList.size()];
int counter2 = 0;
for(String s : outterList)
{
array[counter1][counter2] = s;
counter2++;
}
counter1++;
}
To init String[][], you should init the list(array) of String[]
So you need to define a list
List<String[]> string = new List<String[]>();
for (int i = 0;....)
{
String[] _str = new String[numbers];
_str[0] = ...
string.append(_str);
}
Related
I have a function which processes an ArrayList of String arrays and is supposed to return a two-dimensional array of strings:
public String[][] myFunction() {
ArrayList<String[]> myArrayList = new ArrayList<String[]>();
...
return myArrayList.toArray(String[][]);
}
Which does not work. Casting to type String[][] also does not work:
return (String[][]) myArrayList.toArray();
Note that I need String[][], not Object[][].
How do I get this to work?
You can use the toArray method of the List interface
ArrayList<String[]> myArrayList = new ArrayList<String[]>();
myArrayList.add(new String[] {"A","B","C"});
myArrayList.add(new String[] {"AA","BB","CC"});
String[][] array = myArrayList.toArray(String[][]::new);
System.out.println(Arrays.deepToString(array));
Prints
[[A, B, C], [AA, BB, CC]]
Here are two other approaches. In both cases, they will work fine with different length arrays.
This one simply copies the array that is in the list. So if you alter the contents of any array in the list, the array of arrays will also be altered.
String[][] array = new String[myArrayList.size()][];
for (int i = 0; i < myArrayList.size(); i++) {
array[i] = myArrayList.get(i);
}
This simply makes a copy of the existing array in the list to avoid the problem described previously.
String[][] array = new String[myArrayList.size()][];
for (int i = 0; i < myArrayList.size(); i++) {
String[] arr = myArrayList.get(i);
array[i] = Arrays.copyOf(arr, arr.length);
}
You can try this
static String[][] listTo2dArray(ArrayList<String[]> arlS) {
String[][] arr2D = new String[arlS.size()][arlS.get(0).length];
for(int i =0;i<arlS.size();i++) {
arr2D[i] = arlS.get(i);
}
return arr2D;
}
Assuming you list have same number of elements for every row
How might I convert an ArrayList<String> object to a String[] array in Java?
List<String> list = ..;
String[] array = list.toArray(new String[0]);
For example:
List<String> list = new ArrayList<String>();
//add some stuff
list.add("android");
list.add("apple");
String[] stringArray = list.toArray(new String[0]);
The toArray() method without passing any argument returns Object[]. So you have to pass an array as an argument, which will be filled with the data from the list, and returned. You can pass an empty array as well, but you can also pass an array with the desired size.
Important update: Originally the code above used new String[list.size()]. However, this blogpost reveals that due to JVM optimizations, using new String[0] is better now.
An alternative in Java 8:
String[] strings = list.stream().toArray(String[]::new);
Java 11+:
String[] strings = list.toArray(String[]::new);
Starting from Java-11, one can use the API Collection.toArray(IntFunction<T[]> generator) to achieve the same as:
List<String> list = List.of("x","y","z");
String[] arrayBeforeJDK11 = list.toArray(new String[0]);
String[] arrayAfterJDK11 = list.toArray(String[]::new); // similar to Stream.toArray
You can use the toArray() method for List:
ArrayList<String> list = new ArrayList<String>();
list.add("apple");
list.add("banana");
String[] array = list.toArray(new String[list.size()]);
Or you can manually add the elements to an array:
ArrayList<String> list = new ArrayList<String>();
list.add("apple");
list.add("banana");
String[] array = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
Hope this helps!
ArrayList<String> arrayList = new ArrayList<String>();
Object[] objectList = arrayList.toArray();
String[] stringArray = Arrays.copyOf(objectList,objectList.length,String[].class);
Using copyOf, ArrayList to arrays might be done also.
In Java 8:
String[] strings = list.parallelStream().toArray(String[]::new);
In Java 8, it can be done using
String[] arrayFromList = fromlist.stream().toArray(String[]::new);
If your application is already using Apache Commons lib, you can slightly modify the accepted answer to not create a new empty array each time:
List<String> list = ..;
String[] array = list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
// or if using static import
String[] array = list.toArray(EMPTY_STRING_ARRAY);
There are a few more preallocated empty arrays of different types in ArrayUtils.
Also we can trick JVM to create en empty array for us this way:
String[] array = list.toArray(ArrayUtils.toArray());
// or if using static import
String[] array = list.toArray(toArray());
But there's really no advantage this way, just a matter of taste, IMO.
You can use Iterator<String> to iterate the elements of the ArrayList<String>:
ArrayList<String> list = new ArrayList<>();
String[] array = new String[list.size()];
int i = 0;
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); i++) {
array[i] = iterator.next();
}
Now you can retrive elements from String[] using any Loop.
Generics solution to covert any List<Type> to String []:
public static <T> String[] listToArray(List<T> list) {
String [] array = new String[list.size()];
for (int i = 0; i < array.length; i++)
array[i] = list.get(i).toString();
return array;
}
Note You must override toString() method.
class Car {
private String name;
public Car(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
final List<Car> carList = new ArrayList<Car>();
carList.add(new Car("BMW"))
carList.add(new Car("Mercedes"))
carList.add(new Car("Skoda"))
final String[] carArray = listToArray(carList);
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
String [] strArry= list.stream().toArray(size -> new String[size]);
Per comments, I have added a paragraph to explain how the conversion works.
First, List is converted to a String stream. Then it uses Stream.toArray to convert the elements in the stream to an Array. In the last statement above "size -> new String[size]" is actually an IntFunction function that allocates a String array with the size of the String stream. The statement is identical to
IntFunction<String []> allocateFunc = size -> {
return new String[size];
};
String [] strArry= list.stream().toArray(allocateFunc);
List <String> list = ...
String[] array = new String[list.size()];
int i=0;
for(String s: list){
array[i++] = s;
}
in case some extra manipulation of the data is desired, for which the user wants a function, this approach is not perfect (as it requires passing the class of the element as second parameter), but works:
import java.util.ArrayList;
import java.lang.reflect.Array;
public class Test {
public static void main(String[] args) {
ArrayList<Integer> al = new ArrayList<>();
al.add(1);
al.add(2);
Integer[] arr = convert(al, Integer.class);
for (int i=0; i<arr.length; i++)
System.out.println(arr[i]);
}
public static <T> T[] convert(ArrayList<T> al, Class clazz) {
return (T[]) al.toArray((T[])Array.newInstance(clazz, al.size()));
}
}
In Java 11, we can use the Collection.toArray(generator) method. The following code will create a new array of strings:
List<String> list = List.of("one", "two", "three");
String[] array = list.toArray(String[]::new)
from java.base's java.util.Collection.toArray().
You can convert List to String array by using this method:
Object[] stringlist=list.toArray();
The complete example:
ArrayList<String> list=new ArrayList<>();
list.add("Abc");
list.add("xyz");
Object[] stringlist=list.toArray();
for(int i = 0; i < stringlist.length ; i++)
{
Log.wtf("list data:",(String)stringlist[i]);
}
private String[] prepareDeliveryArray(List<DeliveryServiceModel> deliveryServices) {
String[] delivery = new String[deliveryServices.size()];
for (int i = 0; i < deliveryServices.size(); i++) {
delivery[i] = deliveryServices.get(i).getName();
}
return delivery;
}
An alternate one-liner method for primitive types, such as double, int, etc.:
List<Double> coordList = List.of(3.141, 2.71);
double[] doubleArray = coordList.mapToDouble(Double::doubleValue).toArray();
List<Integer> coordList = List.of(11, 99);
int[] intArray = coordList.mapToInt(Integer::intValue).toArray();
and so on...
I am working on the following coding prompt for my class:
Your task is to write a method with the following signature:
public static String[] removeFromArray(String[] arr, String toRemove)
The method should return a string array that has the same contents as arr, except without any
occurrences of the toRemove string. For example, if your method is called by the code below
String[] test = {“this”, “is”, “the”, “example”, “of”, “the”, “call”};
String[] result = removeFromArray(test, “the”);
System.out.println(Arrays.toString(result));
it should generate the following output:
[this, is, example, of, call]
Note: Your method will be passed values for arr and toRemove by the testing program – you should not
read these values in from the user inside your method. Also, you must write this method with the
signature requested above in order to receive credit. You do not need to write the code that calls the
method – only the method itself.
Hint: Because you must specify the length of an array when you create it, you will likely need to make
two loops through the input array: one to count the number of occurrences of the toRemove string so
that you can create the new array with the proper size and a second to copy all of the other strings to the new array.
I have everything working in my code but the last part where I have to print out the new array does not work, I know I have make it smaller so it will print out properly, but I can't get that part to work. I know I have to get rid of the null, but I don't know how. Also my code has to work for any array not just the test case I have. Some help or advice would really be nice. Thank you very much!!! :)
Here is my code:
public static void main(String[] args) {
String[] test = {"this", "is", "the", "example", "of", "the", "call"};
String[] remove = removeFromArray(test, "the");
System.out.println(Arrays.toString(remove));
}
public static String[] removeFromArray(String[] arr, String toRemove) {
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i].equals(toRemove)) {
count++;
}
}
String[] result = new String[arr.length - count];
//for (int i = 0; i < arr.length; i++) {
// if(!arr[i].equals(toRemove)){
// result[].equals(arr[i]);
//}
//}
return result;
}
you approach looks ok, it looks like the commented code yor are trying to assign the new array with the wrong emthod
you should use result[i] = arr[i] ; instead of result[].equals(arr[i]);
do at the end:
String[] result = new String[arr.length - count];
int k = 0;
for (int i = 0; i < arr.length; i++) {
if(!toRemove.equals(arr[i])){
result[k] = arr[i];
k++;
}
}
return result;
Your last part should be assigning the value to the array one by one.
int j = 0;
for (int i = 0; i < arr.length; i++) {
if(!toRemove.equals(arr[i])){
result[j++] = arr[i];
}
}
It's asking you to return a new String array which excludes the given word. Loop through the array and add word which does not equal to the given word.
public static String[] removeFromArray(String[] arr, String toRemove){
ArrayList<String> words = new ArrayList<>();
for(String s : arr)
if(!s.equals(toRemove))
words.add(s);
return words.toArray(new String[0]);
}
Since array size cannot be changed after being created, use an ArrayList to store the words, then return as an array.
I know you're new to programming itself, so the solutions given are perfectly fine.
However, using Java, you'd usually use the libraries; in this case, the Collections library. If you're using Java 8, this is how you would do it:
public static String[] removeFromArray(String[] arr, String toRemove) {
// create a List and fill it with your items
ArrayList<String> list = new ArrayList();
Collections.addAll(list, arr);
// remove the items that are equal to the one to be removed
list.removeIf(s -> toRemove.equals(s));
// transfer back to array
return list.toArray(new String[list.size()]);
}
Then, there are Java 8 Streams, which would make this
public static String[] removeFromArray(String[] arr, String toRemove) {
return Arrays.stream(arr) // create stream from array
.filter(s -> !toRemove.equals(s)) // filter out items
.toArray(String[]::new); // create array from stream
}
I have a
List<ArrayList> arg = new ArrayList<ArrayList>();
with
[[logo], [cd_branche], [lib_branche]],
(other arguments not relevant)
[[1111,22222,3333]],[[2222,324,432]]...
and I want to cast it to a String[] so I did this
Object[] obj = arg.toArray();
String[] headers =new String[obj.length];
for(int i=0;i<headers.length;i++) {
headers[i]= (String) obj[i];
}
but I'm getting
java.util.ArrayList cannot be cast to java.lang.String
The output I'm looking for is
headers[0]=logo
headers[1]=cd_branche
headers[2]=lib_branche
Using Java 6
It sounds like you want it to be an array of strings (i.e. "[["logo", "cd_branche", "lib_cranche"],[..],[..],[1111,22222,3333],[2222,324,432]").
In that case simply do:
Object[] obj = arg.toArray();
String[] headers =new String[obj.length];
for(int i=0;i<headers.length;i++) {
headers[i]= Arrays.toString(obj);
}
And each one of your ArrayList objects inside obj will be returned in string array format.
UPDATE: Since you want it as a flat array, you'll need to (a) compute the size of the array needed and (b) run through your object with two loops and make a deep search as such:
int size = 0;
for (int i = 0; i < arg.size(); size += arg.get(i++).size());
String[] headers =new String[size];
for(int count = 0, i=0;i<arg.size();i++) {
for (int j=0; j< arg.get(i).size(); j++) {
headers[count++]= arg.get(i).get(j).toString();
}
}
String headers = "";
for (String header:arg)
{headers += header;}
I have written this code, but at run time I have this error:
[Ljava.lang.Object; cannot be cast to [[Ljava.lang.String;
please help me, thanks!!!
public java.util.List<String> concatAll(java.util.List<java.util.List<String>> mergedList) {
java.lang.String [][] mergedArray = (String[][])mergedList.toArray();
Iterator<java.util.List<String>> itr = mergedList.iterator();
java.util.List<String> list1 = itr.next();
java.lang.String [] firstArray = (String[])list1.toArray();
int totalLength = firstArray.length;
for (String[] array : mergedArray) {
totalLength += array.length;
}
String[] result = Arrays.copyOf(firstArray, totalLength);
int offset = firstArray.length;
for (String[] array : mergedArray) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
java.util.List<String> finalList = Arrays.asList(result);
for (String list : finalList)
System.out.println(list);
return finalList;
}
mergedList.toArray() creates a singly indexed array typed as objects.
Each of the objects it contains is in fact a (singly-indexed) list of strings, though with this call syntax the type is not known at compile-time. It is not an array of strings, as would be needed for your cast to work.
Since your concatAll is trying to convert a List<List<String>> into a List<String> by some sort of concatenation operation, it may be best to do this without ever converting to a String[][] at all, but if you do want that conversion, it can be done as follows:
private String[][] toDoubleIndexArray(List<List<String>> mergedList) {
String[][] result = new String[mergedList.size()][];
for (int i = 0; i< mergedList.size(); i++) {
List<String> currentList = mergedList.get(i);
result[i] = currentList.toArray(new String[currentList.size()]);
}
return result;
}
Original answer, not quite correct as noted by Xavi Lopez in comments:
Since mergedList has type List<List<String>>,
mergedList.toArray() has type List<String>[], i.e., it's an array of lists, and not a doubly indexed array.
There's no out-of-the-box method, but it's fairly straightforward to do by hand:
// Create the outer dimension of the array, with the same size as the total list
String[][] mergedArray = new String[mergedList.size()][];
// Now iterate over each nested list and convert them into the String[]
// instances that form the inner dimension
for (int i = 0; i < mergedList.size(); i++) {
mergedArray[i] = mergedList.get(i).toArray(new String[0]);
}
A slightly more efficient version of the loop body would be
List<String> innerList = mergedList.get(i);
String[] innerAsArray = innerList.toArray(new String[innerList.size()]);
mergedArray[i] = innerAsArray;
as this avoids the array resizing that would be required in my initial example (the new String[0] isn't large enough to hold the list elements). But quite frankly, unless this was a performance critical loop, I'd prefer the first version as I find it slightly clearer to see what's going on.
Hey you cannot convert the Multi dimentional String list to String array directly. Add the below code before trying to use the mergedArray:
/** Create Array **/
String [][] mergedArray = new String[mergedList.size()][];
/** Initialize array from list **/
for(int i=0; i< mergedList.size(); i++){
mergedArray[i] = mergedList.get(i).toArray(new String[0]);
}
This should do the trick
I think your return type is wrong if your intention is to return an array of array.
Try this:
public String[][] concatAll(java.util.List<java.util.List<String>> mergedList) {
//java.lang.String [][] mergedArray = (String[][])mergedList.toArray();
java.lang.String[][] mergedArray = new String[mergedList.size()][];
Iterator<java.util.List<String>> itr = mergedList.iterator();
int count = 0;
while (itr.hasNext())
{
java.util.List<String> list1 = itr.next();
String[] array1 = list1.toArray(new String[list1.size()]);
mergedArray[count++] = array1;
}
return mergedArray;
}
You can't convert a
List<List<String>>
to a String[][] by using the out of the box toArray functionality. This would only work if you had:
List<String[]>.