How to copy elements from `2d array` to `Arraylist`? - java

folks, what is the technique of copying elements from array to Arraylist?
public DenseBoard(T[][] x, T fillElem){
ArrayList<ArrayList<T>> myBoard = new ArrayList<ArrayList<T>>();
for(int i = 0; i < x.length; i++){
for(int j = 0; j < x[0].length; j++){
myBoard.get(i).add(j); //<<------ getting error!
}
}
}

You'll need to initialize each member of myBoard in the outer loop:
Untested Code Ahead
public DenseBoard(T[][] x, T fillElem){
ArrayList<ArrayList<T>> myBoard = new ArrayList<ArrayList<T>>();
for(int i = 0; i < x.length; i++){
myBoard.add(new ArrayList<T>); //Gotta add something to stick stuff in
for(int j = 0; j < x[0].length; j++){
myBoard.get(i).add(j); //<<------ no more error?
}
}
}
Since myBoard is an ArrayList of ArrayLists of Ts, we need to give it somewhere to put the T's. Initially, myBoard looks like this:
[] <-- empty ArrayList
So we give it somewhere to put data for each row, like this
myBoard.add(new ArrayList<T>);
Now it looks like
[ [] ] <--- ArrayList with an empty ArrayList in it, ready to accept T's
We add some T's, and end up with this
[ [T1, T2, T3] ].
And on the next iteration, we'll end up with something like this
[ [T1, T2, T3], [T4, T5, T6] ]
Hope that cleared things up.

You are getting error because your are trying to get() a value from ArrayList but not had inserted any value first. To do it your way, here is the correct code :
ArrayList<ArrayList<T>> myBoard = new ArrayList<>();
for(int i = 0; i < x.length; i++){
ArrayList<T> values = new ArrayList<>();
for(int j = 0; j < x[0].length; j++){
values.add(x[i][j]);
}
myBoard.add(values);
}
Just use the following function :
Arrays.asList(T...a)
In your case it will be done as :
ArrayList<T> myBoard = new ArrayList<>();
for(T[] arr : x){
myBoard.add(Arrays.asList(arr));
}
Try to use diamond operator <> to make code more readable
Don't reinvent the wheel, use utilities provided at least by core libraries
Make use of for-each statement where you could

Inspired from this post.
new ArrayList<Item>(Arrays.asList(array))
creates a new ArrayList of Item elements from an input array. For two-dimensionals. In this case, you tried this:
public DenseBoard(T[][] x, T fillElem){
ArrayList<ArrayList<T>> myBoard = new ArrayList<ArrayList<T>>();
for(int i = 0; i < x.length; i++){
for(int j = 0; j < x[0].length; j++){
myBoard.get(i).add(j); //<<------ getting error!
}
}
}
The problem is that the line throwing the error assumes you have an ArrayList of ArrayList, but the inner element you try to refer to is not initialized. This should be a fix:
public DenseBoard(T[][] x, T fillElem){
ArrayList<ArrayList<T>> myBoard = new ArrayList<ArrayList<T>>();
for(int i = 0; i < x.length; i++){
myBoard.add(new ArrayList<T>(Arrays.asList(x[i])));
}
//Do something with myBoard
}

Related

Java - Filling multidimensional (2d) ArrayList like a 2d array

A while ago before I got used to object object oriented programming I created a basic TicTacToe game and to create the board I used an array.
The code is a complete mess because I didn't properly understand how to use objects, but I did initialize the board correctly:
char[][] board = new char[3][3];
for (int i = 0; i < board.length; i++){
for (int j = 0; j < board[i].length; j++){
board[i][j] = '[]' //or something like that...don't remember exactly
}
}
My question is how would you this with an ArrayList?
ArrayList <ArrayList<Character>> board = new ArrayList(); // this initialization is not
// wrong using Java 8 but for earlier versions you would need to state the type on both
//sides of the equal sign not just the left
for (int i = 0; i < board.size(); i++){
for (int j = 0; j < board.get(i).size(); j++){
board.get(i).get(j).add('[]');
}
}
but that does not work.
It does not have to be exactly like this, I just generally want to understand how to handle multidimensional ArrayLists.
-thanks
Unlike arrays, you can't initialize an entire ArrayList directly. You can specify the expected size beforehand (this helps performance when you are using very large lists, so it is a good practice to do it always).
int boardSize = 3;
ArrayList<ArrayList<Character>> board = new ArrayList<ArrayList<Character>>(boardSize);
for (int i = 0; i < boardSize; i++) {
board.add(new ArrayList<Character>(boardSize));
for (int j = 0; j < boardSize; j++){
board.get(i).add('0');
}
}
The main difference is that in your original code you had a multi-dimensional array of primitives (in this case, char) and all you had to do was assign a new primitive value to each slot in the array.
However what you want now is an ArrayList of (ArrayList of Character). When you create the ArrayList it is empty. In order to procede you are going to need to fill it with several (ArrayList of Character) before you can begin to start adding Characters themselves.
So for example,
ArrayList <ArrayList<Character>> board = new ArrayList<>();
for (int i=0; i<3; i++) {
board.add(new ArrayList<Character>());
}
Now you can start adding Characters to your lists:
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
board.get(i).add('A');
}
}
Hope this helps.
First you have to initialize the ArrayList in your first line correctly and than you have to initialize an new ArrayList in each run of your first loop:
ArrayList <ArrayList<Character>> board = new ArrayList<ArrayList<Character>>();
for (int i = 0; i < 3; i++){
ArrayList<Character> innerList = new ArrayList<Character>();
board.add(innerList);
for (int j = 0; j < 3; j++){
innerList.add('[');
}
}

Adding Integers to ArrayList<Integer>

I have an ArrayList of LinkedLists (an array of linked lists). The LinkedLists contains integers (Integer).
private List<LinkedList> buckets;
buckets = new ArrayList<LinkedList>();
for (int i = 0; i < 10; i++) {
LinkedList<Integer> temp = new LinkedList<Integer>();
buckets.add(temp);
}
I later want to remove the items from the linked list (in the order they were added) and add them to an array list. When I try this:
ArrayList<Integer> sorted = new ArrayList<Integer>(unsorted.size());
for (int i = 0; i < buckets.size(); i++) {
for (int j = 0; j < buckets.get(i).size(); j++) {
sorted.add(buckets.get(j).removeLast());
// sorted.add((Integer)buckets.get(j).removeLast());
}
}
I get an error saying:
add(java.lang.Integer) in ArrayList cannot be applied to (java.lang.Object)
But when I cast it to an Integer (the commented out line), the array is full of null values. Anyone see what I am doing wrong?
Here is where I am adding items to bucket:
for (int i = 0; i < unsorted.size(); i++) {
int digit = (unsorted.get(i) / position) % 10;
buckets.get(digit).add(unsorted.get(i));
}
Note that sorted is an ArrayList<Integer>. When I trace it in debug mode, I can see that the LinkedLists have Integer objects with the correct values.
Screenshot of buckets contents:
Working Example:
class Ideone {
private static List<LinkedList<Integer>> buckets;
public static void main (String[] args) throws Exception {
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add(6);
arr.add(8);
arr.add(1);
arr.add(3);
arr.add(9);
System.out.println(arr);
arr = sort(arr);
System.out.println(arr);
}
public static ArrayList<Integer> sort(ArrayList<Integer> unsorted) {
buckets = new ArrayList<LinkedList<Integer>>();
for (int i = 0; i < 10; i++) {
LinkedList<Integer> temp = new LinkedList<Integer>();
buckets.add(temp);
}
ArrayList<Integer> sorted = new ArrayList<Integer>(unsorted.size());
for (int i = 0; i < unsorted.size(); i++) {
int digit = unsorted.get(i) % 10;
buckets.get(digit).add(unsorted.get(i));
}
for (int i = 0; i < buckets.size(); i++) {
for (int j = 0; j < buckets.get(i).size(); j++) {
sorted.add(buckets.get(j).poll());
// sorted.add((Integer)buckets.get(j).removeLast());
}
}
return sorted;
}
}
You are using the raw form of LinkedList here:
private List<LinkedList> buckets;
Because of this, removeLast will return Object, not Integer. Try
private List<LinkedList<Integer>> buckets;
and
buckets = new ArrayList<LinkedList<Integer>>();
Casting the return of removeLast to Integer was the pre-generics way of getting this to work. However, you never inserted any items into each LinkedList, so removeLast returns null. If you want something returned, first insert something into each LinkedList that gets inserted into buckets.
Casting to Integer would still work, but supplying Integer as the type argument to LinkedList is preferred, especially since you are using generics by supplying LinkedList as the type parameter to List already.
In your nested loop,
for (int i = 0; i < buckets.size(); i++) {
for (int j = 0; j < buckets.get(i).size(); j++) {
// ***** here *****
sorted.add(buckets.get(j).poll());
}
}
You look to be polling the wrong List.
Try changing
sorted.add(buckets.get(j).poll());
to:
sorted.add(buckets.get(i).poll());
Perhaps a cleaner more intuitive way to code this would be something like:
for (int i = 0; i < buckets.size(); i++) {
LinkedList<Integer> innerList = buckets.get(i);
for (int j = 0; j < innerList.size(); j++) {
sorted.add(innerList.poll());
}
}
Although this may not work if the innerList has multiple items. Why not instead remove items safely with an iterator?
for (int i = 0; i < buckets.size(); i++) {
LinkedList<Integer> innerList = buckets.get(i);
for (Iterator<Integer> iterator = innerList.iterator(); iterator.hasNext();) {
sorted.add(iterator.next());
iterator.remove(); // this guy is optional
}
}
Either that or simply use get(j)
for (int i = 0; i < buckets.size(); i++) {
LinkedList<Integer> innerList = buckets.get(i);
for (int j = 0; j < innerList.size(); j++) {
sorted.add(innerList.get(j));
}
}
Although this isn't efficient use of a LinkedList
The item that you inserted into the ArrayList "sorted" is the item you took from the link list LinkedList.
But you never actually add any item to it. You simply just created a LinkedList and added it to your bucket list.
You need to add something into the temp list.
for (int i = 0; i < 10; i++) {
LinkedList<Integer> temp = new LinkedList<Integer>();
// Add something to the temp LinkedList
buckets.add(temp);
}

How to get a specific element from a collection of lists?

I have a list myCollection which is a collection of lists like
myCollection = [[1,2,3,4],[1,2,3,4],[1,2,3,4]]
Iterating this list and by get(i) method i will get a particular sublist.
for (int i = 0; i < myCollection.size(); i++) {
System.out.println(myCollection.get(i));
}
I tried creating a new list for the sublist and iterating it but i am getting the complete list as [1,2,3,4]
for (int i = 0; i < myCollection.size(); i++) {
List list = new ArrayList();
list.add(myCollection.get(i));
for (int j = 0; j < list.size(); j++) {
System.out.println("list.get(j) -- "+list.get(j).toString());
}
}
how to get the element in this sublist ?
Thanks
How about this:
list.get(i).get(j)
You might want to try something like this:
List list = new ArrayList();
for (int i = 0; i < myCollection.size(); i++) {
list.add(myCollection.get(i));
}
Its also better to separate your printer:
for (int j = 0; j < list.size(); j++) {
System.out.println("list.get(j) -- "+list.get(j).toString());
}
Try following code:
for (int i = 0; i < myCollection.size(); i++)
{
List myList = myCollection.get(i);
for (int j = 0; j < myList.size(); j++)
{
System.out.println("myList.get(j) -- "+myList.get(j).toString());
}
}
What you are doing is:
list.add(myCollection.get(i));
this line will add the complete list at index i to the list. So, no need to add it to another list. simply store it in a myList variable, as I did. and then iterate.
You are getting list because, you are storing a list in your List.
Also, you have declared a raw type list, which is not a good practice.
You can rather get the individual elements from each nested list using enhanced-for loop: -
myCollection = [[1,2,3,4],[1,2,3,4],[1,2,3,4]]
for(List<Integer> list: myCollection) {
for (Integer intVal: list) {
System.out.print(intVal + " ");
}
System.out.println();
}

ArrayList of ArrayLists - clear function confusion

Here is a particular method I have written:
class A {
private static ArrayList<ArrayList<Integer>> inputTerms = new ArrayList<ArrayList<Integer>();
public static void method1(ArrayList<Integer> terms) {
ArrayList<Integer> clauses = new ArrayList<Integer>();
int N = terms.size();
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
clauses.add(-terms.get(i));
clauses.add(-terms.get(j));
inputTerms.add(clauses);
clauses.clear();
}
}
}
}
This method is called multiple times from the main function.
In the end, i try to write the contents of the class variable into a file. However, when I do this, i get 0 as the contents of inputTerms. However, if i remove the clauses.clear() line, i am able to get approppriate values.
My program is such that it is vital for me to clear the clauses after adding to inputTerms. Is there any alternative to this?
**Hmmm.. I have done what you've suggested. However, I haven't quite overcome the problem. To give more background, in my main function, I have the following code:
for (int i=0; i<N-1; i++){
ArrayList<Integer> firstdiagonalTerms = new ArrayList<Integer>();
for (int j=0; j<N-i; j++){
firstdiagonalTerms.add(variable[j][i+j]);
}
method1(firstdiagonalTerms);
}
I have to call the method1 function 4 times for different combinations of 'i' and 'j'. However, I still get 0 when I use the above mentioned suggestions**
You are adding the same list and clearing it repeatedly. When you add an object to a list it copies a reference to it, not a copy of the object.
int N = terms.size();
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
List<Integer> clauses = new ArrayList<Integer>();
clauses.add(-terms.get(i));
clauses.add(-terms.get(j));
inputTerms.add(clauses);
}
}
or
for (int i = 0, N = terms.size(); i < N - 1; i++)
for (int j = i + 1; j < N; j++)
inputTerms.add(Arrays.asList(-terms.get(i), -terms.get(j)));
Not sure i understand what you are trying to achieve, but you keep reusing the same list, which is probably not what you meant to do.
You should probably move the ArrayList<Integer> clauses = new ArrayList<Integer>(); inside the inner loop, and not call clauses.clear() at all.
When you are adding "clauses" you are adding the actual object to the arrayList, not a copy. So when you clear them all the values in the list will be removed. To get arround this, add a clone of the list:
inputTerms.add((ArrayList<Integer>) clauses.clone());
When you call clear() on list, you are updating/removing same objects (because list contains reference to objects, not copy of object). That is what causing the issue.
I think you need to do something like below. Instead of using clear(), create a new list everytime.
public static void method1 (ArrayList<Integer> terms)
{
int N = terms.size();
for (int i = 0; i<N-1; i++) {
for (int j=i+1; j<N; j++) {
ArrayList<Integer> clauses = new ArrayList<Integer>();
clauses.add(-terms.get(i));
clauses.add(-terms.get(j));
inputTerms.add(clauses);
}
}

set() in ArrayList

I am new to Java, please help me.
My program is
import java.util.*;
import java.lang.*;
class Test
{
public static void main(String[] args)
{
ArrayList al=new ArrayList();
al.add("a");
al.add("b");
for(int i=1;i<=10;i++)
{
al.add(i);
}
al.remove("a");
al.set(1,"c");
for(int j=3;j<=al.size();j++)
{
al.set(j,"z");
}
System.out.println(al);
}
};
in above any mistake........plz help me
a) You need to make the class public to run it:
public class Test
{
b) the last semi-colon is a syntax error No it's not, it's just unnecessary noise.
c) This fails with an IndexOutOfBoundsException:
for(int j = 3; j <= al.size(); j++){
al.set(j, "z");
}
It needs to be:
for(int j = 3; j < al.size(); j++){
al.set(j, "z");
}
Explanation: List Indexes are zero-based, so the highest position in a List with n elements is n-1
BTW, the above code can be written in a more elegant way like this:
Collections.fill(al.subList(3, al.size()), "z");
Reference:
Collections.fill(List<T>, T)
List.subList(from, to)
This code will throw an IndexOutOfBounds exception because of the line:
for (int j = 3; j <= al.size(); j++) {
to fix it, you need to change it to:
for (int j = 3; j < al.size(); j++) {
This is because the <= means that your for loop iterates over the end of the list.
List~ and Arrayindices start at 0, not 1. So if you have a list of 3 Elements, they go from index: 0, 1, 2. So you normally iterate from (i = 0; i < list.size (); ++i). Less than, not less/equal.
for (int j=3; j < al.size (); j++)
1.The semicolon in the last line
2.change the code from
for(int j=3;j<=al.size();j++)
to
for(int j=3;j<al.size();j++)
Arraylist are always accessed from from 0th index to less than the size of the array.
I think it is necessary to change also the start index from 3 to 2:
for (int j=2; j < al.size (); j++)

Categories