I have an ArrayList. I would like to set each element of it to 0. Right now I have:
ArrayList <T extends Number> arr = new ArrayList();
for(int i = 0; i < some_other_array.size(); i++)
{
arr.add(0)
}
The compiler complains that
error: no suitable method found for set(int,int)
arr.add(0);
^
method ArrayList.set(int,T) is not applicable
(actual argument int cannot be converted to T by method invocation conversion)
where T is a type-variable:
T extends Number
It cannot be done. The method signature for is
public T ArrayList<T>.set(int index, T element)
Even though the constraint on T is that it extends Number, it does not mean that it can be constructed from a number.
Consider, for example,
class FortyTwo extends Number {
public byteValue() { return 42; }
public intValue() { return 42; }
// etc
}
What would you expect the initialization routine to do to an ArrayList<FortyTwo> ?
Just change your list declaration to
ArrayList<Number> arr = new ArrayList<Number>();
arr will be capable of holding anything extending Number (which is what you want, I assume).
Now, when you do
arr.set(i, 0)
that 0 will be autoboxed to an Integer. (See for yourself, add 0 and print arr.get(0) instanceof Integer.)
If you wanted to add doubles or longs for instance, you could use the literals 0d and 0L, respectively.
This should work for your case: arr.set(i, Integer.valueof(0));
Or you can reuse this handy standard API: Collections.fill(arr, Integer.valueof(0));
Why you want to set the value to 0, it will be automaticaly zero as ArrayList object will be instantiated. So the code will be useless as the size will be zero at the time so loop will not be executed.
Well, I think you're a little confused about how ArrayList actually works. When you create an ArrayList, it's always empty. Even if you specify a size:
ArrayList<Integer> arr = new ArrayList<Integer>(20);
That 20 just means "initial capacity", not "starting number of elements". As a result, set will never work because there are simply no elements. Even if you fix your compiler issue like this:
arr.set(i, Integer.valueOf(0));
Or like this:
ArrayList<Number> arr = new ArrayList<Number>();
It's not even going to do anything because arr.size() is zero, so the for loop won't even run.
The key here is that ArrayList is not an actual array. It wraps an array, and will expand its inner array when it has too many elements. In other words, I can't do this:
ArrayList<Integer> arr = new ArrayList<Integer>(20);
arr.get(0); // Throws an out of bounds exception
Now, that being said, if you want to start with 20 zeroes in your ArrayList, you can use the add method in your loop and i < 20 instead:
for(int i = 0; i < 20; i++) {
arr.add(Integer.valueOf(0));
}
This will add 20 zeroes to arr. Your code, even after fixing the error, will not.
Try changing the declaration of your ArrayList to
ArrayList<Integer> arr = new ArrayList<Integer>();
The Integer class supports auto-boxing, while the Number class does not. Also, the add() method may be more applicable.
You can try this (to the best of my knowledge, you cannot add primitive types to ArrayList):
ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i = 0; i < someNumber; i++)
{
arr.add(0);
}
Remember that when size is 0 because it does not have any default values and the capacity is what you should be looking at (You can set the capacity in the constructor.)
Related
import java.util.ArrayList;
import java.util.Random;
public static void main(String[] args) {
ArrayList<Integer> random = new ArrayList<Integer>();
random = getRandom(100, 100);
for (int i = 0; i < random.size(); i++)
System.out.println(random.get(i));
}
private static ArrayList<Integer> getRandom(int range, int size) {
ArrayList<Integer> randomNumbers = new ArrayList<Integer>();
for (int i = 0; i < size; i++)
randomNumbers.set(i, new Random().nextInt(range)+1);
return randomNumbers;
}
Whenever I run this, I get an Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
Change
randomNumbers.set(i, new Random().nextInt(range)+1);
to
randomNumbers.add(new Random().nextInt(range)+1);
the set() method of an ArrayList works an EXISTING element of the ArrayList, but in your case it's empty, which means that the first call to
randomNumbers.set(i, new Random().nextInt(range)+1);
where i == 0 is invalid. Use add() instead.
Arraylist are backed by arrays, when you use set method with an index, it tries to set the value at the index since the backed array is empty you get an IndexOutOfBoundsException, so first you need to populate the Arraylist.
For that you need to use the add method, instead of set
In addition to JDev's correct response above, take a look at the description of ArrayList#set's Javadoc:
Replaces the element at the specified position in this list with the specified element.
So, the specified index has to already be populated in order for the ArrayList#set call to succeed.
arrayList.set(index, value) method is used to replace old value with new value. But in your case, you are not replacing a value. You are just simply adding values.
So, Use add method of list.
randomNumbers.add(new Random().nextInt(range)+1);
And for printing the values of Arraylist, you are using:
for (int i = 0; i < random.size(); i++)
System.out.println(random.get(i));
but no need to iterate it through for loop, You can directly print this like below:
System.out.println(random);
If you want, you could also use the functional style:
List<Integer> list = IntStream.range(0, 100)
.mapToObj(i -> random.nextInt(100))
.collect(Collectors.toList());
This will minimize the moving parts that are part of what's causing your problem :)
I am working on a sudoku solving program and I need an arraylist that holds the numbers 1 thru 9 for each of the squares on the 9x9 board. Each of these arraylists correspond to the possible numbers that could go in that square, if a number can not go in that square, it is removed from the list.
I want to be able to pull up the arraylist of the current square it is working on, like for example if I wanted to remove the number 7 from the arraylist corresponding to square (3,5)
arrayOfLists[3][5].remove(Integer.valueOf(7));
However I can't figure out how to do this. When I try to create the array I am getting this error on the line where I declare my array of arraylists
Cannot create a generic array of ArrayList
Here is my code:
//create arraylist
ArrayList<Integer> nums = new ArrayList<Integer>();
//fill arraylist with numbers 1-9
for (int i = 1; i < 10; i++) {
nums.add(i);
}
//create 9x9 array of arraylists
ArrayList<Integer>[][] array = new ArrayList<Integer>[9][9];
//fill each element of array with arraylist of numbers 1-9
for(int i = 0; i<9; i++){
for(int j = 0; j<9; j++){
array[i][j] = nums;
}
}
}
Am I doing this incorrectly or is it not possible to create an array of arraylists? If it is not possible, how should I do this then?
Anytime I see a list of lists, alarm bells start ringing. The situations where you actually want such a thing are rare indeed, and this is not one of them.
You've got a fixed board consisting of 9 fixed squares, columns and rows, each position of which may take a number 1-9.
Use an array for all of these concepts, because they are fixed in size and you need direct access to each element - collections offer no benefit and would be a hindrance. Use logic (possibly sets) to ensure numbers are used only once in each zone.
Use a bit field instead of an array list. That is, use an integer where bits 1-9 represent the possibilities of the numbers. Testing, adding, removing a single number is O(1), and it has a fixed memory size. Encapsulate the integer in its own object that knows the operations.
A few things:
1) In your for loop, array[i][j] = nums; This is going to result in the same object in each element of the array. If you call remove() on one element of the array, it's going to affect all the others. You want to build a separate list object for each element.
2) Program to interfaces; declare nums as a List as opposed to ArrayList.
3) Use a List of Lists as opposed to any array of Lists.
List<List<List<Integer>>> list = new ArrayList<List<List<Integer>>>();
for(int i = 0; i<9; i++){
List<List<Integer>> row = new ArrayList<List<Integer>>();
for(int j = 0; j<9; j++){
List<Integer> nums = new ArrayList<Integer>();
for (int k = 1; k < 10; k++) {
nums.add(i);
}
row.add(nums);
}
list.add(row);
}
// You can still get an element by index
int x = list.get(3).get(1).remove(6);
But this is kind of unwieldy. You might want to consider writing a class that represents the board. That way you'll at least have operations that better abstract this.
You could completely remove the use 2d stuff and keep a single list by giving each square a unique number from 1...81. So if you are working with 3,5 cell that means it's the 9*2+5 = 23rd item in the list. That will greatly simplify the list manipulation. You could use a single method to give the unique cell index given the (3,5) kind of reference
OK, I'm going to post this as an answer since it seems to work for me and I haven't yet seen any pitfalls.
private static class IntegerArrayList extends ArrayList<Integer> {
IntegerArrayList () { super(); }
IntegerArrayList (Collection<? extends Integer> c) { super(c); }
IntegerArrayList (int initialCapacity) { super(initialCapacity); }
}
Now you can say something like
IntegerArrayList[][] array = new IntegerArrayList[9][9];
and elements like array[1][2] will inherit all the ArrayList methods (array[1][2].remove(something) works fine). I made the class private static thinking you could nest it in some other class if that's the only place you'll use it, but you can make it public if you like. Also, I copied all three constructors from ArrayList; you could eliminate unneeded ones but I don't see a compelling reason to.
I think the issue is that new ArrayList<Integer>[9][9] is prohibited because it would create an array that wouldn't do type checking (because of "type erasure"). But I think adding your own non-generic type that inherits from ArrayList<Integer> restores the type safety.
But I'm not a generic expert, and it wouldn't surprise me if someone more knowledgeable than I spots a problem with this solution. But it seemed to work fine for me, with no compiler warnings about unchecked type stuff or anything.
(P.S. I'm posting this as a possible general solution to a problem that gets asked a lot. But in reality, for this particular problem, I might just use a fixed-size array of boolean instead of an ArrayList, like others, or I might even do bit-diddling on integers if speed is a real issue.)
I have loaded the contents of the database in an ArrayList named countList. The contents loaded are of int type. I created countList using the command
ArrayList countList = new ArrayList();
Now, I need to check if each contents of the arraylist is greater than three. I wrote it like
for(int i=0; i< itemset.size(); i++){
if(countList.get(i) >= 3)
{
}
}
When I write it simply, it shows error of bad operand type for binary operator '>='. How to do the task?
The >= operator is only defined on number types such as int, double or Integer, Double. Now, countlist may well contain integers (I assume it does), but the way you have written your code, the compiler can't be sure. This is because an ArrayList can store any type of object, including but not necessarily Integer. There are a couple of ways you can remedy this:
a) You can cast the ArrayList item to an Integer, at which point the >= operator will work:
if ( (Integer) countList.get(i) >= 3)
b) You can use generics to tell the compiler that your ArrayList will ONLY store Integers:
ArrayList<Integer> countList = new ArrayList<Integer>();
for(i=0; i< itemset.size(); i++){
if (itemset.get(i) > 3) {
// Do whatever you want here
}
}
In one class I have constructor which looks like:
Class(int x, int y, int[] moves);
In other class which creates those objects I have moves stored in ArrayList. Moves are numbers. So when this class decides ti create new object it must first convert this ArrayList into array. So I tried something like this:
new Object(0, 0, (int[])moves.toArray(int[moves.size()]);
But it doesn't work. How should it be done properly?
The result of calling toArray() on an ArrayList is never an int[]. You can't have an ArrayList<int> in Java due to the way generics works. At best it would be an Integer[], which you'd then need to convert. Note that even though you can convert from Integer to int, you can't cast an Integer[] to an int[]. Something has to loop over the values.
You could just do it directly:
int[] values = new int[moves.size()];
for (int i = 0; i < values.length; i++) {
values[i] = moves.get(i);
}
Alternatively could create an Integer[] and then convert from that - but why do the copying twice?
I set an array of integer like below
int[] a = new int[11111];
//if I set
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
I want a method such that it gives me
4 but 11111.
Is there any method which I can use?
You should look into using an ArrayList
ArrayList<Integer> myList=new ArrayList<Integer>();
myList.add(1);
myList.add(2);
myList.add(3);
System.out.println("Size:"+myList.size());
Well, the following method will do what you asked for:
public int m() {
return 4;
}
On the assumption that you want a method that takes an array, and returns the greatest index that has been populated - you're right that the a.length only tells you the size of the array, i.e. the number of cells allocated.
This is going to be harder than you might expect, especially with an int array. Those unassigned cells are initialised to a value of 0. If you might actually use zero values in your array, then there is absolutely no way to tell whether the value in a cell is the "default" zero or one that you've set yourself.
If the array can't have zero values in it, then you'd need to loop over its entire length, checking for the highest index with a corresponding non-zero value; something like this:
public int dynamicLength(int[] a) {
int max = -1;
for (i = 0; i < a.length; i++) {
if (a[i] != 0) max = i;
}
return max;
}
Even then this might not be ideal, since arrays can be sparsely populated. Do you want the count of assigned indices, or the index of the highest assigned index?
The short answer is almost certainly "use an ArrayList".
When you do
int[] a = new int[11111]
It creates an array with 11111 elements and as it is int it will assign it to default value that is 0 so you have array with all values set.
You should move to List
You should use an ArrayList if the size of the array is changing. There is little performance difference.
See here for how to use one. See here for the API also.
I understand that you only want the assigned elements to be counted but it would be safer at runtime and simpler to use an ArrayList. The ArrayList class just wraps a Java array and handles the changing size for you. You can get the size by calling the size() method on the ArrayList.
See this example using a for-each loop if you want to iterate over the elements:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1); //size is 1
list.add(2); //size is 2
list.add(3); //size is 3
list.add(4); //size is 4
for(Integer n : list)
System.out.println(n);
An ArrayList uses an iterator and the for-each loop uses it to iterate over the ArrayList. Makes life much simpler.
As suggested above, using a List is probably the right answer. However, in the interest of solving the original problem, you could try this instead:
Integer[] foo = new Integer[11111];
foo[0] = new Integer(1);
foo[1] = new Integer(2);
foo[2] = new Integer(3);
foo[3] = new Integer(4);
and create a method that counts non-null values:
public static int countItems(Integer[] array) {
int count = 0;
for (Integer i : array) {
if (i != null) {
count++;
}
}
return count;
}
Of course, this will be a pain to manage as you would need to nullify any items no longer needed. It also raises the question of whether you would accept "holes" in your array, e.g. null values amongst non-null values. My example counting function above would accept such holes.
So, yes. Use a List.
You can create a method which calculates the non-0 elements of the array using a for/while loop.