I have a list like this:
List<MyObject[]> list= new LinkedList<MyObject[]>();
and on Object like this:
MyObject[][] myMatrix;
How can I assign the "list" to "myMatrix"?
I don't want to loop over the list and assign element by element to MyMatrix, but I want to assign it directly (with the oppurtune modifications) if possible.
Thanks
You could use toArray(T[]).
import java.util.*;
public class Test{
public static void main(String[] a){
List<String[]> list=new ArrayList<String[]>();
String[][] matrix=new String[list.size()][];
matrix=list.toArray(matrix);
}
}
Javadoc
The following snippet shows a solution:
// create a linked list
List<String[]> arrays = new LinkedList<String[]>();
// add some trivial test data (note: arrays with different lengths)
arrays.add(new String[]{"a", "b", "c"});
arrays.add(new String[]{"d", "e", "f", "g"});
// convert the datastructure to a 2D array
String[][] matrix = arrays.toArray(new String[0][]);
// test output of the 2D array
for (String[] s:matrix)
System.out.println(Arrays.toString(s));
Try it on ideone
Let us assume that we have a list of 'int' array.
List<int[]> list = new ArrayList();
Now to convert it into 2D array of type 'int', we use 'toArray()' method.
int result[][] = list.toArray(new int[list.size()][]);
We can generalize it further like-
List<T[]> list = new ArrayList();
T result[][] = list.toArray(new T[list.size()][]);
Here, T is the type of array.
Use toArray() or toArray(T[]) method of LinkedList.
You can do it like this:
public static void main(String[] args) {
List<Item[]> itemLists = new ArrayList<Item[]>();
itemLists.add(new Item[] {new Item("foo"), new Item("bar")});
itemLists.add(new Item[] {new Item("f"), new Item("o"), new Item("o")});
Item[][] itemMatrix = itemLists.toArray(new Item[0][0]);
for (int i = 0; i < itemMatrix.length; i++)
System.out.println(Arrays.toString(itemMatrix[i]));
}
Output is
[Item [name=foo], Item [name=bar]]
[Item [name=f], Item [name=o], Item [name=o]]
assuming that Item is as follows:
public class Item {
private String name;
public Item(String name) {
super();
this.name = name;
}
#Override
public String toString() {
return "Item [name=" + name + "]";
}
}
Converto list to array using. List.Array()
Then Use System.arraycopy to copy to the 2d array works well for me
Object[][] destination = new Object[source.size()][];
System.arraycopy(source, 0, destination, 0, source.size());
Related
// "static void main" must be defined in a public class.
import java.util.*;
public class Main {
static void func(ArrayList<ArrayList<Integer>> arr) {
ArrayList<Integer> arr1 = new ArrayList();
arr1.add(0);
arr.add(arr1);
arr1.set(0,5);
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();
func(arr);
for(int i=0;i<arr.size();i++) {
for(int j=0;j<arr.get(i).size();j++) {
System.out.print(arr.get(i).get(j));
}
System.out.println();
}
}
}
In the above code, we add an 1D arraylist of 1 element (0) to the 2D arraylist arr, but when we change the value in the 1D arraylist from 0 to 5, why is the same change reflected in the 2d arraylist, and most importantly, how exactly do we avoid this?
By default, Java Lists are mutable and you can easily change their content by adding or removing elements. In addition to this, your arr List has a reference to arr1 and not a copy of it. This means that whenever you change 1D this change is also reflected in arr because both arr1 and the content of arr reference to the same exact List.
One way to avoid this is actually copying the arr1 List before adding it to arr as follows:
static void func(ArrayList<ArrayList<Integer>> arr) {
ArrayList<Integer> arr1 = new ArrayList<>();
arr1.add(0);
arr.add(new ArrayList<>(arr1));
arr1.set(0,5);
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();
func(arr);
for(int i=0;i<arr.size();i++) {
for(int j=0;j<arr.get(i).size();j++) {
System.out.print(arr.get(i).get(j));
}
System.out.println();
}
}
Mind the changed line arr.add(new ArrayList<>(arr1));. This guarantees that the reference that arr holds is different than the reference of the original arr1. You are basically creating a new List.
Although this fixes your case, it might not work for every List because it depends on its content. This works on your case because Integer is an immutable class, but if you would have a List of a mutable class, then this wouldn't be enough because both Lists would reference exactly the same objects. An example of this is below:
public static void main(String[] args) {
ArrayList<ArrayList<MutableClass>> arr = new ArrayList<>();
ArrayList<MutableClass> arr1 = new ArrayList<>();
arr1.add(new MutableClass("original"));
arr.add(new ArrayList<>(arr1));
System.out.println(arr.get(0));
// now let's change the property of arr1 MutableClass to something else
arr1.get(0).setProperty("changed");
System.out.println(arr.get(0));
}
public static class MutableClass {
private String property;
public MutableClass(String property) {
this.property = property;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
#Override
public String toString() {
return "MutableClass{" +
"property='" + property + '\'' +
'}';
}
}
As you can see by running the code, changing the object in arr1, also changes the object in arr even if you create a new List. The only way to overcome this is by making MutableClass immutable or by deep copying the original arr1 List before adding it to arr. This means you would need to copy every single object inside arr1 as follows:
public static void main(String[] args) {
ArrayList<ArrayList<MutableClass>> arr = new ArrayList<>();
ArrayList<MutableClass> arr1 = new ArrayList<>();
arr1.add(new MutableClass("original"));
ArrayList<MutableClass> copiedList = new ArrayList<>();
for (MutableClass object : arr1) {
copiedList.add(new MutableClass(object));
}
arr.add(copiedList);
System.out.println(arr.get(0));
// now let's change the property of arr1 MutableClass to something else
arr1.get(0).setProperty("changed");
System.out.println(arr.get(0));
}
public static class MutableClass {
private String property;
public MutableClass(String property) {
this.property = property;
}
public MutableClass(MutableClass other) {
this.property = other.property;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
#Override
public String toString() {
return "MutableClass{" +
"property='" + property + '\'' +
'}';
}
}
To avoid 5 getting reflected in 2D list
create a new array list from arr1 in method func() and add it to arr(the 2D list) as shown below.
static void func(ArrayList<ArrayList<Integer>> arr) {
ArrayList<Integer> arr1 = new ArrayList();
arr1.add(0);
arr.add(new ArrayList<>(arr1));
arr1.set(0,5);
}
The reason for the behaviour:
Java is pass by value
When we do
func(arr);
in main method, the reference to the actual array list object in heap is passed as value to the method "func()".
Inside func, hence arr will be pointing to the same object.
When we add the array list newly created arr1 into arr, the reference to actual object corresponding to arr1 gets added to the actual 2D array.
This is because both arr of func() as well as arr of main() refers to same object in heap.
When we try to change something in arr1 list,
it is referenced by arr. So, it will be still visible to arr.
Printing the list in main gives output 5.
But when we create a new array list and add that to arr in func(), as below
arr.add(new ArrayList<>(arr1));
then the list got added to arr will be different from arr1.
Hence,
while printing in main(),
the 2D list holds the reference to newly created array list
(ie; new ArrayList<>(arr1)).
So, it will not get affected by changing to 5 by the line
arr1.set(0,5);
This will still give 0 while printing the list arr in main().
This programm shuffles a source list by pairs. So that original list
"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"
trasfoms to
11^12 19^20 17^18 15^16 1^2 5^6 3^4 13^14 7^8 9^10
The above is true while commented line is uncommented. Now, if line A is commented then all the elements in shuffleList are 19^20.
public class ShuffleService {
public static void shuffleList(List<String> list) {
System.out.println(list);
ArrayList<String[]> shuffleList = new ArrayList<String[]>(10);
String[] arr = new String[2];
boolean flag = false;
int step = 0;
for(String s: list){
if(flag){
arr[1]=s;
} else {
arr[0]=s;
}
flag=!flag;
step++;
if(step==2){
shuffleList.add(arr);
step=0;
//arr = new String[2]; //**line A**
}
}
Collections.shuffle(shuffleList);
for(String[] val: shuffleList){
System.out.print(val[0]);
System.out.print("^");
System.out.println(val[1]);
}
}
public static void main(String[] args) {
String[] a = new String[]{"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"};
List<String> list1 = Arrays.asList(a);
shuffleList(list1);
}
}
So why do I need to uncomment line A in the program to work properly?
Because when you rewrite the values to arr (without remaking it), you're also going to modify the values already in the list.
Adding an object to the list doesn't stop you from modifying it, it will not make copies on its own. By calling new String[2] in your loop you're effectively building a new string array for each pair that you add to the list, which is what you want.
Basically I have two arrays each filled with the same number of values (although the number of values in each array will stay the same, the number of these values can increase or decrease etc.)
The first array list has a list of names e.g.
Sam
Dean
Alice
Jane
Steve
The second array list has a list of index locations which I would like the above items to be stored at with a 3rd list-array e.g.
2nd array index locations.
3
2
5
1
4
I have used arraylists as below:
ArrayList namelist = new ArrayList();
Simply sort the list with names. You can use Collections.sort() because the strings are compareable. Then create the new list an add the string in the order of the indices.
List<String> newList = new ArrayList<>(); // or new ArrayList<String>(); for source level below 1.7
Collections.sort(nameslist);
for(Integer idx : indexList)
{
newList.add(nameslist.get(idx - 1));
}
You have to create a third array with the same size as the other two. Then you have to use the values of intArray as indices for the sortedStrArray like so:
public class JavaApplication
{
// Utilisation
public static void main(String[] args)
{
// The arrays are just here to make the initialization shorter.
// You can initialize strArrayList and
// intArrayList from the beginning with the add method if you want.
String strArray[] = new String[] { "Sam", "Dean", "Alice", "Jane", "Steve" };
Integer intArray[] = new Integer[] { 3, 2, 5, 1, 4 };
// Put array data in ArrayLists
List<String> strArrayList = new ArrayList<String>(Arrays.asList(strArray));
List<Integer> intArrayList = new ArrayList<Integer>(Arrays.asList(intArray));
List<String> sortedList = sortArrayListByIndices(strArrayList, intArrayList);
// Output order should be: Jane, Dean, Sam, Steve, Alice
for(String str : sortedList)
{
System.out.println(str);
}
}
// Implementation
public static List<String> sortArrayListByIndices(List<String> strArrayList,
List<Integer> intArrayList)
{
String sortedStrArray[] = new String[strArrayList.size()];
int i = 0;
for(String str : strArrayList) // Iterator is better style
{
// indices start with 1, array starts with 0
final int index = intArrayList.get(i) - 1;
sortedStrArray[index] = str;
i++;
}
return new ArrayList<String>(Arrays.asList(sortedStrArray));
}
}
The desired algorithm has its own method now and I wrote a little program that utilizes/tests it.
I have a series of String[] arrays which are list of words. Something like:
String[] ListOne = new String[100];
String[] ListTwo = new String[100];
/*And so on with other lists */
ListOne[0] = "word00";
ListOne[1] = "word01";
/*And so on till*/
ListLast[99] = "word 99 from last list";
Now I want a function for each list that, given a number returns the corresponding element (word):
public String GetFromListOne(int key) { return ListOne[key];}
Is there a way to avoid manually writing each of this getter functions?
In PHP, for example, I would just use the magic method __call,
or pass as an argument with the list name and reference it dynamically.
Is there a way to do something similar in Java?
Or an alternative strategy to achieve the same result?
You should look into inheritance.
What you basically must do is define an interface (or extend a List class)
public interface ListTest{
//**Gets keys from lists*//
GetFromListOne(int key);
}
then
public class Listone implements ListTest{
/** methods **//
GetFromListOne(int key);
/** methods **//
}
Have fun extending
http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html
You could use a 2 dimensional array, or a list of arrays and have your function take 2 parameters. One for the array that you want and the other for the element in the array.
2 dimensional array:
String[][] ListN = new String[100,100];
String getFromList(int n, int key) {
return ListN[n][key];
}
Or list of arrays:
List<String[]> listOfArrays = new ArrayList<String[]>();
listOfArrays.add(new String[100]);
listOfArrays.add(new String[100]);
String getFromList(int n, int key) {
return listOfArrays.get(n)[key];
}
Could you have a function that takes as input the key and the list number:
public String GetFromListOne(int list, int key) {
switch(list):
case 1:
return ListOne[key];
break;
case 2:
return ListTwo[key];
break;
...
}
or even better make an array of arrays:
String[][] ListOfLists = new String[10];
ListOfLists[0] = new String[100];
...
public String GetFromList(int list, int key) {
return ListOfLists[list][key];
}
Otherwise I don't know of a function to override like __call
String[] ListFour=new String[100];
String[] ListTwentyThree=new String[100];
String[] ListNine=new String[100];
String[] ListOne=new String[100];
Hashtable<Integer,String[]> yourlist=new Hashtable<Integer,String[]>();
yourlist.put(4, ListFour);
yourlist.put(23, ListTwentyThree);
yourlist.put(9, ListNine);
yourlist.put(1, ListOne);
System.out.println(yourlist.get(4)[5]);//fifth string in ListFour
System.out.println(yourlist.get(23)[51]);//fifty first string in List23
System.out.println(yourlist.get(9)[1]);//first stringin ListNine
another version:
Hashtable<Object,String[]> yourlist=new Hashtable<Object,String[]>();
yourlist.put("two multiplied by two", ListFour);
yourlist.put(23, ListTwentyThree);
yourlist.put(0.03, ListNine);
yourlist.put(true, ListOne);
System.out.println(yourlist.get("two multiplied by two")[5]);//fifth string in ListFour
System.out.println(yourlist.get(23)[51]);//fifty first string in List23
System.out.println(yourlist.get(true)[1]);//first stringin ListNine
Based in the __call PHP method, you can achieve this implementing a method that receives the list and the index, and using generics you can get something like this.
public class Utility {
public <T> T getElementFromArray(T[] array, int index) {
if (index >= array.length || index < 0) return null;
return array[index];
}
}
The pitfall of this method is that can't be used for primitive array holders, like int[]. The solution for these cases would be using the wrapper classes for primitive types.
public static void main(String[] args) {
Utility u = new Utility();
String[] ss = new String[2];
ss[0] = "Hello";
ss[1] = "world!";
System.out.println(u.getElementFromArray(ss, 0));
System.out.println(u.getElementFromArray(ss, 1));
int[] ii = new int[2];
ii[0] = 5;
System.out.println(u.getElementFromArray(ii, 0)); //compile error
//Solution: use wrapper classes
Integer[] ii2 = new Integer[2];
ii2[0] = 5;
System.out.println(u.getElementFromArray(ii2, 0));
}
Try this code
List<String[]> lists = new ArrayList<String[]>();
public String getFromLists(int key) {
List<String> res = new ArrayList<String>();
for (String[] s: lists){
res.add(s[key]);
}
return res.get(key);
}
or better
public String getFromLists(int key) {
return lists.get(key)[key];
}
My arraylist contains String array objects.
How Can I get all values?
My code is below,
String cordinates1c,cordinates2l,cordinates2m;
String[] array1={cordinates1c,cordinates2l,cordinates2m};
String[] array2={cordinates1c,cordinates2l,cordinates2m};
ArrayList alist=new ArrayList();
alist.add(array1);
alist.add(array2);
//retreieving
for(int i=0;i<alist.size();i++)
System.out.println("arrayList="+alist.get(i));
if I try to retrieve like above it gives,
07-12 12:42:09.977: INFO/System.out(743): arrayList=[[Ljava.lang.String;#43e11b28]
How to do that?
Arrays should be printed with the help of Arrays.toString() or Arrays.deepToString().
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
String[][] a = {{"a", "b", "c"}, {"d", "e"}};
System.out.println(Arrays.deepToString(a));
}
}
for(int i=0;i<alist.size();i++) {
for (String a : alist.get(i)) {
System.out.println(a);
}
}
You have to iterate over the array of strings, too.
You can iterate over your List and then use Arrays.toString() or Arrays.deepToString() to print array contents
for (String[] eachArray : alist) {
System.out.println("arrayList=" + Arrays.deepToString(eachArray));
}
ArrayList<String[]> l;
for (String[] a : l) {
for (String s : a) {
System.out.println(s);
}
}
Hoping that you are trying to print the string in array1
ArrayList<String> alist= (ArrayList<String>) Arrays.asList(array1);
Now print the data from alist.
also have a look into alist.addAll(collection)
But following snippet will add array1 and array2 object to your ArrayList, So retrieval you will get an array object
alist.add(array1);
alist.add(array2);
Are you looking for something like this ?
String cordinates1c = "1", cordinates2l = "2", cordinates2m = "3";
String[] array1 = {cordinates1c, cordinates2l, cordinates2m};
String[] array2 = {cordinates1c, cordinates2l, cordinates2m};
List<String []> alist=new ArrayList<String []>();
alist.add(array1);
alist.add(array2);
for (String[] strings : alist) {
System.out.println(StringUtils.join(strings));
}
Output:
123
123