ArrayList of ArrayLists - clear function confusion - java

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);
}
}

Related

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

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
}

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);
}

linked list NullPointerException

I am getting NullPointerException and I don't know why.
LinkedList<Character>[][] list = new LinkedList[n][n];
for (int j = 0; j < n; ++j)
{
for (int m = 0; m < 1; m++)
{
// Here is the problem
list[j][m].add("" + (characterArray[j]));
}
}
I want to add characters from an array to the list. When I run it it says NullPointerException. I don't know how to initialize the list.
You made an array, but you failed to put any LinkedList objects into the array. You need to assign a new LinkedList to list[j][m] before you go adding characters to it.
The problem here is that you created an two dimensional array of LinkedList objects. But remember that the default value for objects in Java is null, so when the array is first created you have a 2 dimensional array of nulls. In the nested for loops you are trying to populate the linkedlist objects you think you have but you don't (Their value is null). So basically you say
null.add("" + (characterArray[j]));
obviously this creates a null pointer exception.
So the solution is to make the object (in this case make a new LinkedList object) before trying to add to it. Either by having a separate 2 nested for loops as follows:
for(int j = 0; j < n; j++)
{
for(int m = 0; m < n; m++)
{
list[j][m] = new LinkedList<Charater>();
}
}
followed normally by your code for the nested loops.
Or you can just declare the object inside your nested for loops
for (int j = 0; j < n; ++j)
{
for (int m = 0; m < 1; m++)
{
// Here is the problem
list[j][m] = new LinkedList<Charater>();
list[j][m].add("" + (characterArray[j]));
}
}

Array List Loop Out of Bounds

I've got this code which I am developing below. I want to loop through two array lists, the first list I want to look at every entry, the second I only want to look at every 3rd entry and see if they match. If they do match then I want to compare the other two entries on the 2nd list. The problem with the code lies in the "int result1 = " line, I can't understand why it would say out of bounds. Any help much appreciated!
for (int i = 0; i < array1.size(); i++){
for (int j = 3; j <array2.size(); j = j + 3) {
if ((array1.get(i)).equals(array2.get(j-3))){
int result1 = array2.get(j-1).compareTo(array2.get(j-2));
}
}
}
This is an extended comment, not an answer.
It is clear that the posted code cannot produce the stated exception. There is something else going on. You need to prepare a Simple, Self-Contained, Correct Example that produces the exception. Here is an example of a program based on the code you posted that does not reproduce the problem. You need to post something similar, but with enough of your actual code to get the exception.
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Integer> array1 = new ArrayList<Integer>();
List<Integer> array2 = new ArrayList<Integer>();
for (int i = 0; i < 100; i++) {
array1.add(0);
array2.add(0);
}
int result = 0;
for (int i = 0; i < array1.size(); i++) {
for (int j = 3; j < array2.size(); j = j + 3) {
if ((array1.get(i)).equals(array2.get(j - 3))) {
int result1 = array2.get(j - 1).compareTo(array2.get(j - 2));
result += result1;
}
}
}
System.out.println(result);
}
}

Categories