Get String from ArrayList inside an ArrayList inside an ArrayList - java

I need to get three levels down into an array list. Here is my code on how I create the final product "rowList":
ArrayList<ArrayList> rowList = new ArrayList<ArrayList>();
ArrayList<ArrayList<String>> appList =new ArrayList<ArrayList<String>>();
ArrayList<String> arr = new ArrayList<String>();
int Id = -1;
int cc = rsmd.getColumnCount();
while(rs.next()){
if(Id == -1){
arr.add(rs.getString("name"));
Id= Integer.parseInt(rs.getString("Id"));
}
if(Id!= Integer.parseInt(rs.getString("Id"))){
Id= Integer.parseInt(rs.getString("Id"));
rowList.add(appList);
appList = new ArrayList<ArrayList<String>>();
arr.add(rs.getString("name"));
}
for(int i=2; i < rsmd.getColumnCount();i++){
arr.add(rs.getString(rsmd.getColumnName(i)));
}
appList.add(arr);
arr = new ArrayList<>();
}
rowList.add(appList);
So in the end rowlist will look something like this:
[0]
[0]
[0]Property 1
[1]Property 2
[2]Property 3
[1]
[0]Property 1
[1]Property 2
[2]Property 3
[1]
[0]
[0]Property 1
[1]Property 2
[2]Property 3
[1]
[0]Property 1
[1]Property 2
[2]Property 3
So my question would be how to get to the properties, the last level in the nested array? I can use rowList.get(0).get(0).toString() to return the string array, but rowList.get(0).get(0).get(0) doesn't work, and instead gives the error: cannot find symbol.
I would also like to be able to remove a property after I've retrieved it and set it to a string. That part can easily be worked around though, so it isn't vital.

This is because you're using a raw type:
ArrayList<ArrayList> rowList = new ArrayList<ArrayList>();
rowList.get(0) returns an ArrayList. Antoher .get(0) will return an Object, because you're using a raw type. And Object does not have a get method.
But Object does have a toString method, so you can call toString.
You simply have to change the declaration. This can be made easier using the diamond:
ArrayList<ArrayList<ArrayList<String>>> rowList = new ArrayList<>();
ArrayList<ArrayList<String>> appList = new ArrayList<>();
ArrayList<String> arr = new ArrayList<>();

Okay, let's think about the type of each result in the chained calls rowList.get(0).get(0).get(0). The easiest way to do this is to break each call into its own line so that we can figure out the type we need for the variable declaration. First of all, look at the declaration of rowList:
ArrayList<ArrayList> rowList = new ArrayList<ArrayList>();
This tells us that rowList.get(0) will return an ArrayList:
ArrayList arr = rowList.get(0);
Now rowList.get(0).get(0) is equivalent to arr.get(0). But this returns an Object:
Object obj = arr.get(0);
So rowList.get(0).get(0).get(0) is equivalent to obj.get(0). However, Object does not have a method named get(). This is why you get an error message.
In general, you should be very careful when chaining method calls. Typically this syntax is only used when a method returns a reference to the calling object. That way the return type is always the same and much easier to keep track of. When the return type differs on each successive method call, it can be difficult to keep track of.
The problem is that the ArrayList returned by rowList.get(0) is a raw type. So another get() call only returns an Object. You should use generics to specify the type of object in the "rows":
ArrayList<ArrayList<ArrayList<String>>> rowList = new ArrayList<>();
As you see here, generics can be used as the type inside of any <> just like you already did for the outermost level of ArrayList in your originaly code. (Note that in JDK 7+, you can use the diamond operator when creating an ArrayList. This greatly reduces duplicating the type information that already appears in the declaration.)
Better yet, you can declare your variables using the List interface in order to provide some flexibility in the concrete type used:
List<List<List<String>>> rowList = new ArrayList<>();

Related

Java: how to create a list cons that accepts lists for the first element

When I create a Java list and I want that the head is a list, should it print a [[-1,0],1,2,3,4] or its alright it just leave the sublist [-1, 0] as two separated elements like [-1, 0, 1, 2,3,4] and, how can I get the first structure as an aswer.
From your post I guess you are asking about how to create a list "construct" in Java which contains both list and non-list elements.
In Java all elements of your list/array need to have the same type. In the example you posted ([[-1,0],1,2,3,4]), the elements are not all the same type. What you have is this: [List<Integer>, Integer, Integer, Integer, Integer]. The first one is different, which isn't allowed in Java.
So, what you need to do is make it so that all elements of your list/array are the same type.
For your case, where there are only integers in your list, the easiest thing to do is to change your types to this: [List<Integer>, List<Integer>, List<Integer>, List<Integer>, List<Integer>] (with your specific values: [[-1,0],[1],[2],[3],[4]]). Instead of a list of List<Integer> and Integer, you now have a list containing only List<Integer> (some of your lists happen to contain only 1 element, but that is ok).
This is called a "two-dimensional list" and depending on whether you want to code it with arrays or java.util.Lists you can code it in one of the following ways:
// with arrays
int[] myTwoDarr = int[5][];
myTwoDarr[0] = new int[]{-1, 0};
myTwoDarr[1] = new int[]{1};
myTwoDarr[2] = new int[]{2};
myTwoDarr[3] = new int[]{3};
myTwoDarr[4] = new int[]{4};
// With Lists
List<List<Integer>> myList = new LinkedList<>();
List<Integer> nestedList1 = new LinkedList<>();
nestedList.add(-1);
nestedList.add(0);
myList.add(nestedList1);
List<Integer> nestedList2 = new LinkedList<>();
nestedList2.add(1);
myList.add(nestedList2);
...etc...
Now, if you absolutely must have different kinds of data in your list, you can create a list of Object instead.
In Java Object is a type from which all non-primitive types inherit. Thus, as long as something is not a primitive, it is an Object and can go in a list of Object. This will allow you to put any kind of data in the elements of your list. Using Object allows you to have a list of all the same type which looks like this: [Object, Object, Object, Object, Object]. But, now Java does not know the specific types you actually have stored in your elements so you will need to type cast when getting them.
Here's an example using a java.util.List:
List<Object> myList = new LinkedList<>();
List<Integer> nestedList = new LinkedList<>();
nestedList.add(-1);
nestedList.add(0);
myList.add(nestedList);
myList.add(1);
myList.add("a string");
// You need to cast when taking elements out of the list.
List<Integer> newNest = (List<Integer>) myList.get(0);
Integer myInt = (Integer) myList.get(1);
String myString = (String) myList.get(2);
Since all your base data types are the same (Integer/int) I recommend avoiding the Object list method and going with the 2D list. It's simpler and less error prone to not do all this casting.

Java/P5: How to declare an Array of Arraylists holding FloatLists?

If I can declare an Array of FloatLists: FloatList [][] values = new FloatList[3][3];
Why doesn’t it work to declare an Array of ArrayLists holding FloatLists like this: ArrayList<FloatList> [][] values = new ArrayList<FloatList>() [3][3];? OR EVEN: ArrayList<FloatList> [][] values = new ArrayList<FloatList> [3][3]();
How can this be achieved? Will it be hard to refer to the floats buried deep under its crusty texture?
Work from the inner-most type to the outer-most type. You start with FloatList:
FloatList
Then wrap that in an ArrayList:
ArrayList<FloatList>
Then you want an array of that:
ArrayList<FloatList>[]
Or a 2D array:
ArrayList<FloatList>[][]
That gives you the type for the declaration, but then you have to initialize the variable by giving it a value. Start with the array by giving it a size:
ArrayList<FloatList>[] array = new ArrayList[10];
This gives you an array of ArrayList<FloatList> objects, but they start out as null. To give them a value, you'd loop over every index in the array and use the new keyword to set the value of the index to an instance of ArrayList<FloatList>:
for(int i = 0; i < array.length; i++){
array[i] = new ArrayList<FloatList>();
}
For a 2D array, you'd use the same logic, just in a nested for loop.
Then to add a FloatList to an ArrayList at a specific index of the array, you'd do this:
array[i].add(new FloatList());
Finally, to add a float to a FloatList in an ArrayList at an index in the array, you'd do this:
array[x].get(y).append(0.5);
And to get a float out of an index in the FloatList in an ArrayList at an index in the array, you'd do this:
float f = array[x].get(y).get(z);
Putting it all together, it looks like this:
ArrayList<FloatList>[] array = new ArrayList[10];
for(int i = 0; i < array.length; i++){
array[i] = new ArrayList<FloatList>();
}
array[1].add(new FloatList());
array[1].get(0).append(0.25);
array[1].get(0).append(0.5);
array[1].get(0).append(0.75);
float f = array[1].get(0).get(2);
println(f);
ArrayList<FloatList> [][] values = new ArrayList[3][3];
Basically, you're declaring that you want an object that is a 3D array of ArrayLists, and not generating actual ArrayList objects.
Afterwards, you have to instantiate each of them, so for example:
values[0][0] = new ArrayList<>();
And so on.
It doesn't work because of the way the JVM provides Generics. Generics in Java is a front-end compiler feature that becomes raw type usages and casts at execution time.
What is the compiler doing when I use generics?
Here's a terribly-contrived example. Let's say I want to create a List<String> to store command line arguments that I will later use to kick off a new process with, like so:
List<String> cmd = new ArrayList<>();
cmd.add("java");
cmd.add("-jar");
cmd.add("path/to/my.jar");
...
String args = cmd.get(0)+" "+cmd.get(1)+" "+cmd.get(2);
At compile time, the compiler will check to make sure that I am using the String type every time I use a generic List method via cmd and throw an error if I try to use instances of an incompatible type. However, there's a little thing called erasure that happens during compilation, before execution. Effectively, under the hood, the compiler converts the code above into something like this:
List cmd = new ArrayList();
cmd.add("java");
cmd.add("-jar");
cmd.add("path/to/my.jar");
...
String args = (String)cmd.get(0)+" "+(String)cmd.get(1)+" "+(String)cmd.get(2);
So why doesn't my generic array code compile?
In your example, you wanted to create an array of a generic type, like so:
ArrayList<FloatList>[][] array = new ArrayList<FloatList>[n][m]; //Doesn't compile? What gives?
The problem is, because of type erasure, the ArrayList<FloatList> class type doesn't really exist, and now you've asked the JVM to create a 2-dimensional array of that non-existent type.
Okay, so what's the alternative?
Well ... it isn't pretty, but you could do something like this:
class ArrayListOfFloatList extends ArrayList<FloatList>{
...
}
//Somewhere else in your code:
ArrayListOfFloatList[][] myArray = new ArrayListOfFloatList[n][m];
//This will compile because ArrayListOfFloatList is a real class.
The only other way around this would be to not use arrays. Ugly, perhaps, but it's unfortunately a limitation of how Java is currently implemented.

Modifying bigInteger after dividing Java

I've looked a lot through here and can't quite find why this line is wrong:
ArrayList <BigInteger> data = new ArrayList();
int [] primes = new int[25];
...
// Some initializing
...
data.get(i) = data.get(i).divide( BigInteger.valueOf( primes[place] ) ); //<----
...
// Rest of the code
Required: variable;
Found: value.. What I'm doing wrong?
First, you should fix your Raw Type (and I'd prefer the List interface) like
List<BigInteger> data = new ArrayList<>();
then you need to use set because you can't assign to the return value of a get like that.
data.set(i, data.get(i).divide(BigInteger.valueOf(primes[place])));
Also, it's worth noting that BigInteger(s) are (per the Javadoc) immutable arbitrary-precision integers.
= only works to assign variables, fields and array elements.
You probably want to call set.
data.set(i, data.get(i).divide(...etc...));

casting Arrays.asList causing exception: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList

I'm new to Java and am trying to understand why the first code snippet doesn't cause this exception but the second one does. Since a string array is passed into Arrays.asList in both cases, shouldn't both snippets produce an exception or not produce an exception?
Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList
First snippet (causes no exception):
ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String line = "a,b,cdef,g";
String delim = ",";
String[] pieces = line.split(delim);
stuff.add((ArrayList<String>) Arrays.asList(pieces));
Second snippet (causes above exception):
ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((ArrayList<String>) Arrays.asList(titles));
If relevant, I'm using JavaSE 1.6 in Eclipse Helios.
For me (using Java 1.6.0_26), the first snippet gives the same exception as the second one. The reason is that the Arrays.asList(..) method does only return a List, not necessarily an ArrayList. Because you don't really know what kind (or implementation of) of List that method returns, your cast to ArrayList<String> is not safe. The result is that it may or may not work as expected. From a coding style perspective, a good fix for this would be to change your stuff declaration to:
List<List<String>> stuff = new ArrayList<List<String>>();
which will allow to add whatever comes out of the Arrays.asList(..) method.
If you do this, you won't get any CCE:
ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(new ArrayList<String>(Arrays.asList(titles)));
As the error clearly states, the class java.util.ArrayList isn't the same as nested static class java.util.Arrays.ArrayList. Hence the exception. We overcome this by wrapping the returned list using a java.util.ArrayList.
The problem is you specified your List to contain ArrayLists - and by implication no other List implementations. Arrays.asList() returns its own implementation of a List based on the implementation of the array parameter, which may not be an ArrayList. That's your problem.
More broadly, you have a classic code style problem: You should be referring to abstract interfaces (ie List), not concrete implementations (ie ArrayList). Here's how your code should look:
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = { "ticker", "grade", "score" };
stuff.add((List<String>) Arrays.asList(titles));
I have tested this code, and it runs without error.
No need to cast manually. This simple code may help you,
List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
Using a debugger, I determined that Array.asList(titles) returns an "Arrays$ArrayList" (ie an inner class of the Arrays class) rather than a java.util.ArrayList.
It's always best to use the interface on the left side of expressions, in this case List rather than the concrete ArrayList. This works fine:
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((List<String>) Arrays.asList(titles));
If you want to use your property as ArrayList<'T'> you need only declare there and create a getter.
private static ArrayList<String> bandsArrayList;
public ArrayList<String> getBandsArrayList() {
if (bandsArrayList == null) {
bandsArrayList = new ArrayList<>();
String[] bands = {"Metallica", "Iron Maiden", "Nirvana"};
bandsArrayList.addAll(Arrays.asList(bands));
}
return bandsArrayList;
}
Initializes the variable and use the method [addAll (Collection collection)](http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll(java.util.Collection))
First, Arrays.asList() should be never casted to ArrayList. Second, since generics were introduced into java programming language casting is still relevant when using legacy, pre-generics APIs.
Third, never use concrete classes at the left of assignment operator.
Bottom line, say
List<List<String>> stuff = new ArrayList<List<String>>();
String line = "a,b,cdef,g";
String delim = ",";
String[] pieces = line.split(delim);
stuff.add(Arrays.asList(pieces));
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(Arrays.asList(titles));
and be happy.

How to cast ArrayList<> from List<>

Can somebody please explain me why I can't cast List<> to ArrayList<> with first approach and I do with second one? Thank you.
First approach:
ArrayList<Task> tmp = ((ArrayList<Task>)mTrackytAdapter.getAllTasks(token));
Second approach:
ArrayList<Task> tmp = new ArrayList<Task>(mTrackytAdapter.getAllTasks(token));
When you do the second one, you're making a new arraylist, you're not trying to pretend the other list is an arraylist.
I mean, what if the original list is implemented as a linkedlist, or some custom list? You won't know. The second approach is preferred if you really need to make an arraylist from the result. But you can just leave it as a list, that's one of the best advantages of using Interfaces!
When you are using second approach you are initializing arraylist with its predefined values.
Like generally we do
**ArrayList listofStrings = new ArrayList<>();
**
Let's say you have an array with values, now you want to convert this array into arraylist.
you need to first get the list from the array using Arrays utils.
Because the ArrayList is concrete type that implement List interface. It is not guaranteed that method asList, will return this type of implementation.
List<String> listofOptions = (List<String>) Arrays.asList(options);
then you can user constructoru of an arraylist to instantiate with predefined values.
ArrayList<String> arrlistofOptions = new ArrayList<String>(list);
So your second approach is working that you have passed values which will intantiate arraylist with the list elements.
More over
ArrayList that is returned from Arrays.asList is not an actual arraylist, it is just a wrapper which doesnt allows any modification in the list.
If you try to add or remove over Arrays.asList it will give you
UnsupportedOperationException
Try running the following code:
List<String> listOfString = Arrays.asList("Hello", "World");
ArrayList<String> arrayListOfString = new ArrayList(listOfString);
System.out.println(listOfString.getClass());
System.out.println(arrayListOfString.getClass());
You'll get the following result:
class java.util.Arrays$ArrayList
class java.util.ArrayList
So, that means they're 2 different classes that aren't extending each other. java.util.Arrays$ArrayList signifies the private class named ArrayList (inner class of Arrays class) and java.util.ArrayList signifies the public class named ArrayList. Thus, casting from java.util.Arrays$ArrayList to java.util.ArrayList and vice versa are irrelevant/not available.
The second approach is clearly wrong if you want to cast. It instantiate a new ArrayList.
However the first approach should work just fine, if and only if getAllTasks return an ArrayList.
It is really needed for you to have an ArrayList ? isn't the List interface enough ? What you are doing can leads to Runtime Exception if the type isn't correct.
If getAllTasks() return an ArrayList you should change the return type in the class definition and then you won't need a cast and if it's returning something else, you can't cast to ArrayList.
Just try this :
ArrayList<SomeClass> arrayList;
public SomeConstructor(List<SomeClass> listData) {
arrayList.addAll(listData);
}
You can cast List<> to ArrayList<> if you understand what you doing. Java compiler won't block it.
But:
It's bad practice to casting parent type to child type (or interface to implementation type) without checking.
This way better:
if (list instanceof ArrayList<Task>) {
ArrayList<Task> arraylist = (ArrayList<Task>) list;
}
Maybe you don't need implementation type as reference. Look SonarQube warning https://sbforge.org/sonar/rules/show/squid:S1319. You can avoid this casting in the most cases.
You can use Guava method:
ArrayList<Task> arraylist = Lists.newArrayList(list);
The first approach is trying to cast the list but this would work only if the List<> were an ArrayList<>. That is not the case. So you need the second approach, that is building a new ArrayList<> with the elements of the List<>
Because in the first one , you're trying to convert a collection to an ArrayList.
In the 2nd one , you just use the built in constructor of ArrayList
May be:
ArrayList<ServiceModel> services = new ArrayList<>(parking.getServices());
intent.putExtra("servicios",services);
import java.util.List;
import java.util.Arrays;
import java.util.*;
public class Merge
{
public static void main(String[] args) {
// This is normal way
// List<Integer> l1 = new ArrayList<Integer>(); l1.add(2); l1.add(5); l1.add(10); l1.add(22);
// List<Integer> l2 = new ArrayList<Integer>(); l2.add(3); l2.add(8); l2.add(15);
//Array.asList only have the list interface, but ArrayList is inherited from List Interface with few more property like ArrayList.remove()
List<Integer> templ1 = Arrays.asList(2,5,10,22);
List<Integer> templ2 = Arrays.asList(3,8,12);
//So creation of ArrayList with the given list is required, then only ArrayList.remove function works.
List<Integer> l1 = new ArrayList<Integer>(templ1);
List<Integer> l2 = new ArrayList<Integer>(templ2);
List<Integer> l3 = new ArrayList<Integer>();
Iterator itr1 = l1.iterator();
while(itr1.hasNext()){
int x = (Integer) itr1.next();
Iterator itr2 = l2.iterator();
while(itr2.hasNext()) {
int y = (Integer) itr2.next();
if(x < y) {
l3.add(x);
break;
}
else{
l3.add(y);
itr2.remove();
}
}
}
Iterator it = l1.iterator();
while (it.hasNext()){
int k = (Integer) it.next();
if (l3.contains(k)){
continue;
}
else{
l3.add(k);
System.out.println(k);
}
}
Iterator itr2 = l2.iterator();
while (itr2.hasNext()){
int k = (Integer) itr2.next();
l3.add(k);
}
System.out.println(l3);
}
}

Categories

Resources