Java - ArrayList default initial values - java

When you create an arraylist of type Integer in Java what are the default values? I need to check if an arraylist is full and I was going to get the size of the array then get the value at the last index and check if it was the default value.
Is there a better way? What would be the default value?
Hope that makes sense. Cheers
int size = a.size();
int last = a.get(size);
if( last == null )
{
return true;
}else{
return false;
}
Edit;
Is it possible to create an ArrayList with a max size that you can not go over to stop it dynamically expanding?
When you create an ArrayList and you use size() would that return the actual size or the amount of elements in the arraylist?
When doing this to create a max size would the default values be null?
public boolean isFull()
{
int size = a.size();
int last = 0;
try{
last = a.get(size-1);
}catch (Exception e){
}
if( last == null )
{
return true;
}else{
return false;
}
}
I currently have this, how does it look? Does this make sense now?

When you declare an ArrayList it is empty. It is also a dynamic container meaning it will grow so for you to ask if it is "full" is more of a constraint you'd need to add to your code.
So, if you want to achieve a goal like you describe.
List<Integer> list = new ArrayList<Integer>();
int MAX_ELEMENTS = 5; //Set this to however you want to constrain the datatype
public boolean addElement(Integer value) {
if (list.size() < MAX_ELEMENTS) {
list.add(value);
return true;
} else {
return false;
}
}
public boolean isFull() {
return (list.size() == MAX_ELEMENTS);
}
public Integer getLast() {
if (!list.isEmpty())
return list.get(list.size()-1);
else
return null;
}
As others have stated though, if you generate a list with a preset size as such:
List<Integer> list = new ArrayList<Integer>(10);
You'd have a list of 10 elements large all being null in value. Should you add additional elements the list will still grow larger than 10 elements unless you constrain it like I did above.

If you haven't actually added Integers to the ArrayList, then any get() on the list will return an IndexOutOfBoundsException.
The size() method returns the number of elements in the list (i.e. how many you have added to it), not the current capacity.

By default ArrayList capacity is 10. All of them are null by default until you add your elements into it. But calling size() will give you number of elements that you have added. It wont give 10 as result(default null values will not be considered). Twist here is if you add null values to the list then they are included while calculating size(). Example if you add 3 valid Integers and 2 null values into the list then size() will return 5. Eclipse debugging will help you in finding this dynamic increasing of its capacity.

When you create an ArrayList, inside the ArrayList class, there is an array of elements. Those elements are set to null because they do not refer to any instance of an Integer object. Bare in mind, that isn't the same as an int.
Moreover, an ArrayList doesn't get full. It is dynamic, and will increase in size when it needs to.
Edit: in response to your edit about setting a maximum size, if you want a maximum size then I'm not sure why you'd want an arraylist. But if you want to stick with an ArrayList class, I would create my own class that is a subclass of arraylist, and override the add method with a check to ensure the value of size() isn't over a fixed amount.

There is not such thing like "full" ArrayList. The size() method will return the number of elements it currently holds.

Do you want to simply constraint the list to a given size, or do you want to check if it is larger than a given size?
Check if list is larger than:
if (list.size() > limit)
System.out.println("List too large");
Its not possible to constraint the size of an ArrayList - you can however create your own subclass of ArrayList that does just that:
public class LimitedList<E> extends ArrayList<E> {
private int limit;
public LimitedList(int limit) {
this.limit = limit;
}
public boolean add(E e) {
// only add if the limit is not exceeded
if (size() < limit)
super.add(e);
}
// overwriting the addAll()-methods is left as an excercise to the reader
}
You only need to decide what the list should DO when one attempts to add more elements than the limit allows. Either just ignore the elements or throw an Exception.

ArrayLists have no default values. If you give the ArrayList a initialCapacity at initialization, you're just giving a hint for the size of the underlying array—but you can't actually access the values in the ArrayList until you add the items yourself.

Any List implementation has a isEmpty() method you can use.

Related

How can I check if an element exists at an index in a LinkedList

I have class called Modul and am adding elements of them to my LinkedList. Now I want to write a method where I input an Integer and check if there is an element at that index of the list or if it is empty. if there is a element i will return it and if not i want to return null and an error message.
I have thought of using an if-statement, but ultimately can't think of a method that checks whether or not an element is present. Now I thought of using try-catch but I don't know what kind of error I would need to catch.
import java.util.LinkedList;
public class Modulhandbuch {
private String nameStudienordnung;
private LinkedList<Modul> liste;
public Modulhandbuch(String nameStudienordnung) {
this.nameStudienordnung = nameStudienordnung;
liste = new LinkedList<Modul>();
}
public void einfuegenModul(Modul m) {
liste.add(m);
}
public int anzahlModule() {
return liste.size();
}
public Modul ausgebenModul(int i) {
try {
return liste.get(i);
}catch() //I don't know what error i would need to catch
}
}
You get a null pointer exception if you give the method an integer value that is bigger than the size of the list, because this index does not exist, so you need to check that. The method below correctly handles that case.
public Modul ausgebenModul(int i) {
if (i >= anzahlModule)
return null;
else
return liste.get(i);
}
indexing a linked list is waste of memory it takes O(n) to get to that index in a linkedList if you insist on this then you can add a property to the Node int index and through the constructer Node() increase this and set that instance to that value now there are few little problems to this what happens when you remove a Node at the Start ? yeah big problem the whole list must be reindexed thats makes the process of remove from Start which is O(1) a O(n) operation
you can do a trick to index it or give an illusion of been indexed is just don't do it when you ask for list(6) the iterator counts 6 Nodes Starting with 0 and stop at that Node

Store and find if a certain array is already stored

My program checks multiple boolean arrays (length 30 each) and I would like to know if I already checked that array. I thought the best way to handle this problem would be to store all the arrays and search for the new array in the set of all the arrays but I don't know what structure I should use. At first, I though hashtable would be the best but it looks like I can't use them with arrays. I looked for set and list but I have no clue what to use !
Edit/clarification: Hey it's my first question here and I'm surprised how many answers I received, thanks a lot ! Lot of people says they are unsure about what exactly I'm looking for so I'll try to clarify:
I have multiple boolean arrays of length 30 where the order is important ( order of elements in the array).
I receive one array at a time and I want to check if I already received the same array (same element, same order). I don't need to store them( I don't need any index, I don't want to know how many arrays I received), don't need anything except to know if I already received the array.
A boolean array is basically a list of bits. Since array size is 30, and an int is a 32-bit value, you can convert the array into an int. With a long you could support arrays up to 64 in size.
So, first convert your array to an int:
private static int toBits(boolean[] array) {
if (array.length > 32)
throw new IllegalArgumentException("Array too large: " + array.length);
int bits = 0;
for (int i = 0; i < array.length; i++)
if (array[i])
bits |= 1 << i;
return bits;
}
Then keep track using a Set<Integer>:
private Set<Integer> alreadySeen = new HashSet<>();
private boolean firstTime(boolean[] array) {
return ! this.alreadySeen.add(toBits(array));
}
This provides a very fast and low-memory implementation that can handle lots of boolean arrays.
You can create a Wrapper class that holds array (content) and a flag. And, instead of storing array of arrays, you can store array of objects of this class. Have a look at the example below:
public class ArrayWrapper {
private boolean checked;
private boolean[] content;
/**
* #return the checked
*/
public boolean isChecked() {
return checked;
}
/**
* #param checked the checked to set
*/
public void setChecked(boolean checked) {
this.checked = checked;
}
/**
* #return the content
*/
public boolean[] getContent() {
return content;
}
/**
* #param content the content to set
*/
public void setContent(boolean[] content) {
this.content = content;
}
}
Now, you can create a List<ArrayWrapper> or ArrayWrapper[], iterate through it and set checked to true once the array (content) is checked.
Use Arrays.equals(array1, array2)
This method returns true if the two specified arrays of booleans are equal to one another. Two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal.
I’m giving you a brute force solution.
List<boolean[]> arrs = new ArrayList<>();
while (true) {
boolean[] receivedArr = receive();
for (boolean[] existingArr : arrs) {
if (Arrays.equals(existingArr, receivedArr)) {
drop(receivedArr);
break;
}
arrs.add(receivedArr);
}
}
You can try an adjacency list or perhaps an array/arraylist of an Object that you call 'Pair' for example where this object has two attributes , the first is an array(the array you checked or didn't check yet) and the second attribute is a boolean value that denotes whether this array has been visited or not.
You can use an array :)
If you have n arrays, then create a boolean array of size n. Let's call it checked[].
So if checked[5] == true, you already checked the fifth array.
Another option would be to use the index 0 of each array as the 'checked flag'.
Thanks for your clarification!
HashMap is still a good answer using Arrays.hashCode() to create your key object. Like so:
HashMap<Integer, Boolean> checked = new HashMap<>();
/**
* Returns true if already checked; false if it's new
*/
public boolean isChecked(Boolean [] array) {
int hashCode = Arrays.hashCode(array);
Boolean existing = checked(hashCode);
if (existing == null) {
checked.put(hashCode, true);
return true;
}
return false;
}

Implementing an equals() method to compare contents of two 'bag' objects

I am working on a school assignment. The objective is to practice GUI's, clone() methods, and using/ modifying existing code. I am trying to write an equals method in the way the instructor desires-- by using a clone of the object, removing items from the bag (returns boolean based on success or failure to remove).
The bag is represented in an array, and should return true in cases such as {1,2,3} and {3,2,1}, ie order does not matter, only the number of each number present in the arrays.
Here is the issue
It works in most cases, however there is a bug in cases where the bags contain numbers as such: {1,1,2} and {1,2,2} and other similar iterations. It is returning true instead of false.
I believe it has something to do with the remove() method we are supposed to use. If i understand it correctly, it is supposed to put the value at the 'end' of the array and decrease the manyItems counter (this is a variable for number of items in the array, because array.length is by default in the constructor 10.)
The code is largely written by another person. We had to import the existing files and write new methods to complete the task we were given. I have all the GUI part done so i will not include that class, only the used methods in the IntArrayBag class.
A second pair of eyes would be helpful. Thanks.
public class IntArrayBag implements Cloneable
{
// Invariant of the IntArrayBag class:
// 1. The number of elements in the bag is in the instance variable
// manyItems, which is no more than data.length.
// 2. For an empty bag, we do not care what is stored in any of data;
// for a non-empty bag, the elements in the bag are stored in data[0]
// through data[manyItems-1], and we don�t care what�s in the
// rest of data.
private int[ ] data;
private int manyItems;
public IntArrayBag( )
{
final int INITIAL_CAPACITY = 10;
manyItems = 0;
data = new int[INITIAL_CAPACITY];
}
public IntArrayBag clone( )
{ // Clone an IntArrayBag object.
IntArrayBag answer;
try
{
answer = (IntArrayBag) super.clone( );
}
catch (CloneNotSupportedException e)
{ // This exception should not occur. But if it does, it would probably
// indicate a programming error that made super.clone unavailable.
// The most common error would be forgetting the "Implements Cloneable"
// clause at the start of this class.
throw new RuntimeException
("This class does not implement Cloneable");
}
answer.data = data.clone( );
return answer;
}
public int size( )
{
return manyItems;
}
public boolean remove(int target)
{
int index; // The location of target in the data array.
// First, set index to the location of target in the data array,
// which could be as small as 0 or as large as manyItems-1; If target
// is not in the array, then index will be set equal to manyItems;
for (index = 0; (index < manyItems) && (target != data[index]); index++)
// No work is needed in the body of this for-loop.
;
if (index == manyItems)
// The target was not found, so nothing is removed.
return false;
else
{ // The target was found at data[index].
// So reduce manyItems by 1 and copy the last element onto data[index].
manyItems--;
data[index] = data[manyItems];
return true;
}
}
//I added extra variables that are not needed to try to increase readability,
//as well as when i was trying to debug the code originally
public boolean equals(Object obj){
if (obj instanceof IntArrayBag){
IntArrayBag canidate = (IntArrayBag) obj; // i know this can be changed, this was required
IntArrayBag canidateTest = (IntArrayBag) canidate.clone(); //this was created
//as a clone because it was otherwise referring to the same memory address
//this caused items to be removed from bags when testing for equality
IntArrayBag test = (IntArrayBag) this.clone();
//fast check to see if the two objects have the same number of items,
//if they dont will return false and skip the item by item checking
if (test.size() != canidateTest.size())
return false;
//the loop will go through every element in the test bag it will
//then remove the value that is present at the first index of the test bag
for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
int check = test.data[i];
//remove() returns a boolean so if the value is not present in each bag
//then the conditional will be met and the method will return false
boolean test1 = test.remove(check);
boolean test2 = canidateTest.remove(check);
if (test1 != test2)
return false;
}//end for loop
// if the loop goes through every element
//and finds every value was true it will return true
return true;
}//end if
else
return false;
}//end equals
}
I cannot see the big picture, as I havent coded GUIs in Java before, however, as far as comparing 2 int[] arrays, I would sort the arrays before the comparison. This will allow you to eliminate problem cases like the one you stated ( if sorting is possible), then apply something like:
while(array_1[index]==array_2[index] && index<array_1.length)
{index++;}
and find where did the loop break by checking the final value of index
Is it explicitly stated to use clone? You can achieve it easily by overriding the hashCode() for this Object.
You can override the hashCode() for this object as follows:
#Override
public int hashCode() {
final int prime = 5;
int result = 1;
/* Sort Array */
Arrays.sort(this.data);
/* Calculate Hash */
for(int d : this.data) {
result = prime * result + d;
}
/* Return Result */
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || this.getClass() != obj.getClass()){
return false;
}
return false;
}
If you want to continue using your implementation for equals to compare test and CandidateTest then also you can compute unique hashes and make decision based on the results.
Here is the code snippet:
/* Assuming that you have put size comparison logic on top
and the two objects are of same size */
final int prime = 31;
int testResult = 1;
int candidateTestResult = 1;
for(int i = 0; i < test.size(); i++) {
testResult = prime * testResult + test.data[i];
candidateTestResult = prime * candidateTestResult + candidateTest.data[i];
}
/* Return Result */
return testResult == candidateTestResult;
I believe the problem is in this line:
for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
The problem here is that test and canidateTest are the clones that you made, and you are removing elements from those bags. And any time you remove an element from the bag, the size will decrease (because you decrease manyItems, and size() returns manyItems). This means you're only going to go through half the array. Suppose the original size is 4. Then, the first time through the loop, i==0 and test.size()==4; the second time, i==0 and test.size()==3; the third time, i==2 and test.size()==2, and you exit the loop. So you don't look at all 4 elements--you only look at 2.
You'll need to decide: do you want to go through the elements of the original array, or the elements of the clone? If you go through the elements of the clone, you actually never need to increment i. You can always look at test.data[0], since once you look at it, you remove it, so you know test.data[0] will be replaced with something else. In fact, you don't need i at all. Just loop until the bag size is 0, or until you determine that the bags aren't equal. On the other hand, if you go through the elements of this.data (i.e. look at this.data[i] or just data[i]), then make sure i goes all the way up to this.size().
(One more small point: the correct spelling is "candidate".)
Maybe you should try SET interface
view this in detail :http://www.tutorialspoint.com/java/java_set_interface.htm
A set object cannot contains duplicate elements, so it's suitable for your assignment than build your own class.
For example:[1,1,2] and [1,2,2]
you can use this to test whether they are equal
arr1 = {1,1,2}
arr2 = {1,2,2}
Set<Integer> set = new HashSet<Integer>();
for(int i : arr1){//build set of arr1
if(set.contains(i)==false){
set.add(i)
}
}
for(int i:arr2){
if(set.contains(i)==false){
System.out.println('not equal');
break;
}
}
Hope this is helpful.

Rearrange order of an ArrayList

I want to rearrange an ArrayList by iterating through it and copying each element to a specific place in a new list.
In this case I want to move an element to the end of the list. For example, if the list is ABCDE and j == B then the new list should be ACDEB.
Here's my code:
private ArrayList<Job> schedule;
private ArrayList<Job> tempSchedule;
...
schedule = input;
tempSchedule = new ArrayList<Job>(schedule.size());
...
private void moveJob(int j) {
for(int i = 0; i < schedule.size(); i++) {
if(i == j) { //move to the end
tempSchedule.set(schedule.size()-1, schedule.get(i));
} else {
if(i > j && i <= schedule.size() -1) { //move one position back
tempSchedule.set(i - 1, schedule.get(i));
} else { //same position
tempSchedule.set(i, schedule.get(i));
}
}
}
schedule = tempSchedule;
u++;
}
Right now I get an IndexOutOfBoundsException: Index: 0, Size: 0 at tempSchedule.set
I guess the problem is with this line
tempSchedule = new ArrayList<Job>(schedule.size());
Also please explain how to make deep copies.
Edit: Thanks for all the answers. I got it to run by simply removing the item and adding it at the end, like suggested.
The reason I wanted to construct a new list is because I might have to do more complex rearrangements at some point.
First, go read the javadoc on ArrayList and collections.
new ArrayList(capacity) doesn't copy, it just allocates a list with that capacity. To copy the list (and it's not a clone, it's a by reference copy, again you need to go back to basics) would be new ArrayList(oldArrayList).
Secondly, Your test has size 0, so there's no objects in it, so get(0) (correctly and as per spec) throws an index out of bounds exception because your list is empty.
Beyond that, neither set nor get will modify the list, so if you had created your copy correctly and it's contents were ABCD and you executed that operation, it's contents would then be ABCB. what you want is.
X = tempSchedule.remove(i) // removes element at I
tempSchedule.add(X) // adds element to end of list
tempSchedule is initialized to be empty:
tempSchedule = new ArrayList<Job>(schedule.size());
You can't use set on an empty ArrayList. It expects the index you are replacing to already have a value.
You get the exception in this line - tempSchedule.set(i, schedule.get(i)); - when i==0.
set calls RangeCheck :
/**
* Checks if the given index is in range. If not, throws an appropriate
* runtime exception. This method does *not* check if the index is
* negative: It is always used immediately prior to an array access,
* which throws an ArrayIndexOutOfBoundsException if index is negative.
*/
private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
}
As you can see, the index you pass to it must be smaller than the current size of the list.
The problem is that your tempSchedule list is empty. set() overwrites the element at the given position. If your list is empty, it can't do that.
This might be a little confusing since you wrote new ArrayList<Job>(schedule.size()). But the parameter you are passing doesn't set the size but the initial capacity, meaning the initial size of the underlying array, which can be used before it has to be resized.
Reason is when you define arrayList with size of schedule, its an empty list i.e. contains nothing.
So when you try to set an element (which is used to replace the existing element), it compares the index with size of your list and finds that index is 0 and size is 0 as well.
Note just by passing size as constructor, you are not changing the size of arrayList. So in order to avoid this, you need to use:
tempSchedule = new ArrayList<Integer>(schedule);
instead of
tempSchedule = new ArrayList<Integer>(schedule.size());
You have the IndexOutOfBoundsException because you are using schedule.size in your for loop while it's null you have to use tempSchedule.size instead.
And you are comparing i and j while you have to compare tempSchedule.get(i) and j.
You have a syntax fallacy as every other answer stated.
I'm more concerned on your approach.
Can't you just simply do:
private void moveJob(int j) {
Job toMove = tempSchedule.get(j);
tempSchedule.remove(j);
tempSchedule.add(toMove);
}
Or yet more concise:
private void moveJob(int j) {
tempSchedule.add(tempSchedule.remove(j));
}

Creating an arraylist of nulls and then setting the index to an object

Really need help with this as a Patient is not getting set to replace the null. We have to create an arraylist of 50 nulls so the iterator goes through the list and if it finds a null it will set it to the patient. The problem is no patients are getting set to the null. We have to return the bed number at the end too.
protected int amountOfBeds = 50;
ArrayList<Patient> bedList = new ArrayList<Patient>(amountOfBeds);
public int admitPatient(Patient illPatient) {
int index = -1;
if(illPatient.getAge() > 0 && amountOfBeds > size()) {
//if it is null then set to patient
//if it not null then we assume its a patient so we skip
Iterator<Patient> itr = bedList.iterator();
try{
while(itr.hasNext()) {
int bedIndex = bedList.indexOf(itr.next());
if(bedList.get(bedIndex).equals(null)) {
bedList.set(bedIndex, illPatient);
index = bedIndex +1;
break;
}
}
}catch(NullPointerException e) {
e.getMessage();
}
}
return index;
}
Simple way to create 50 nulls list is this
List<Patient> list = Collections.nCopies(50, null);
quick way to find index of null is this
int i = list.indexOf(null);
In Java, an ArrayList is basically an array, that can change its size during execution time. Since you seem to have a fixed amound of beds, an array would probably be better here.
The constructor new ArrayList(50) doesn't create an ArrayList with 50 elements. It creates an empty ArrayList, but gives Java the "hint, that there will probably be inserted 50 elements into the ArrayList. If you don't give such a hint, the ArrayList starts with little space and is periodically made bigger, if it gets too small too accomodate all items you want to insert. This takes time, so if you already know how many items you will insert (even if you only know it approximately) this constructor makes your code faster.
However, you have to think if you really need to do this the way you just wanted to do. Whouldn't it be easier, to just have an empty ArrayList, to which you can add or delete elements just as you want to (without a complicated logic, which replaces null with an element. You could then just add if (array.size() >= 50) // it is full, so some special case may be needed here to make sure there are never more elements in the array than you want.

Categories