ArrayList beds = new ArrayList(49);
public Patient getPatient(int bedNumber) {
if (beds.get(bedNumber) != null) {
return (Patient) beds.get(bedNumber);
}
else {
return null;
}
}
I'm having a problem where I can't seem to get Java to output null in a method.
Say I assign a patient to an item in the beds ArrayList, then try to get the patient at the 11th bed using the getPatient method created above, however you can't as 11 patients haven't been added. How can I make it output null when I try to do this instead of java.lang.IndexOutOfBoundsException.
First off, the compiler has nothing to do with this as it's the JVM that's showing the IndexOutOfBoundsException.
What you should do is check your bedNumber against the size of the ArrayList, not whether the ArrayList item that doesn't exist (is out of bounds) is null. So do simple int math.
i.e.,
if (bedNumber > 0 && bedNumber < beds.size()) {
// do your stuff here
} else {
// myself, I'd throw an exception here, not return null
}
You can just modify the if statement to check the size of the ArrayList.
ArrayList beds = new ArrayList(49);
public Patient getPatient(int bedNumber) {
if (bedNumber < beds.size()) {
return (Patient) beds.get(bedNumber);
}
else {
return null;
}
}
While the advice in the other answers is pretty good, one thing that's overlooked is the constructor on your [raw] ArrayList.
new ArrayList(49) will only set the initial capacity of your ArrayList before it has to resize. That doesn't impact how large the array list is at all; if you haven't added any elements into it, its size will still report 0.
Check your bounds; if they enter in a value that's larger than what you support, then reject it.
// The zeroth location in a list is the first element in it.
if(0 <= bedNumber && bedNumber < beds.size()) {
// Cast necessary since it's a raw ArrayList
// Totally avoidable if you use ArrayList<Patient>
return (Patient) beds.get(bedNumber);
} else {
return null;
}
The point here is that your beds List actually has size of zero. So beds.get(i) whatever the i be would throw that exception as it should. I think you are mistaking the way we define array in Java with defining an ArrayList
Related
I need to write a Java method called findMax within a class called Node, which has two instance variables: int value and Node next. The method takes no parameters, and must return the greatest value of a linked list. Within the context of the program, the method will always be called by the first Node of a linked list (except for the recursive calls). I was struggling to complete the method when I accidentally found a working solution:
public int findMax(){
int max = value;
if(next == null){
return max;
}
else{
if(max <= next.findMax()){
max = next.value;
}
else return max;
}
return next.findMax();
}
This method properly returned the largest value of each linked list I tested it for. However, since I found this solution by trying random arrangements of code, I don't really feel like I understand what's going on here. Can anyone explain to me how/why this works? Also, if there is a more efficient solution, how would it be implemented?
You can imagine a linked list looking something like this:
val1 -> val2 -> val3 -> null
Recursion works on the principle that eventually, the input you pass into the function can be handled without recursing further. In your case, node.findMax() can be handled if the next pointer is null. That is, the max of a linked list of size 1 is simply the value (base case of the recursion), the max of any other linked list is the max of the value of that node or the max of the remaining elements.
ie) for the Node n3 with value val3, n3.findMax() simply returns the value
For any other node n, n.findMax() returns the maximum of the node's value or n.next.findMax()
The way this looks in the example at the start is:
n1.findMax()
= Max(n1.value, n2.findMax())
= Max(val1, Max(n2.value, n3.findMax())
= Max(val1, Max(val2, n3.value)) // Since n3.next == null
= Max(val1, Max(val2, val3))
which is simply the maximum over the whole list
Edit: Based on the discussion above, although what you said might work, there is a simpler way of writing the program:
int findMax() {
if (this.next == null) {
return this.value;
} else {
return Math.max(this.value, this.next.findMax());
}
}
Edit 2: A break down of why your code works (and why it's bad):
public int findMax(){
// This variable doesn't serve much purpose
int max = value;
if(next == null){
return max;
}
else{
// This if condition simply prevents us from following
// the else block below but the stuff inside does nothing.
if(max <= next.findMax()){
// max is never used again if you are here.
max = next.value;
}
else return max;
}
// We now compute findMax() again, leading to serious inefficiency
return next.findMax();
}
Why is this inefficient? Because each call to findMax() on a node makes two subsequent calls to findMax() on the next node. Each of those calls will generate two more calls, etc.
The way to fix this up is by storing the result of next.findMax() like so:
public int findMax() {
if (next == null) {
return value;
}
else {
int maxOfRest = next.findMax();
if(value <= maxOfRest) {
return maxOfRest;
}
else return value;
}
}
This is hw and I am really stuck on how to get my code to return what I want it to return. I am trying to return a String value with a given index value. I thought all I had to do was return the string value at the given index but I am not getting the right answer.
public void add(String candidate){
if (candidate.equals(null)){
throw new RuntimeException();
}
String[] contenders = new String[candidates.length+1];
// copy the array manually because I'm restricted from ArrayLists
for (int i = 0; i < candidates.length; i++){
contenders[i] = this.candidates[i];
}
this.candidate = candidate;
contenders[contenders.length-1] = this.candidate;
this.candidates = new String [contenders.length];
After adding values to a newly constructed array the tester wants to get the string value at a given index
public String get(int index){
if (index < 0 || index > candidates.length) {
throw new RuntimeException("Your argument was not within bounds.");
}
for (int i = index; i < candidate.length(); i++){
candidate = candidates[index];
}
return candidate;
I have been working on it and I finally was able to have candidate stop pointing to null it is giving the wrong value for the given index so for example I want 'X' at candidate[3] but I am getting 'Y' because that is the last value that candidate keeps. I have tried just returning candidates[index] but then it tells me that the value at that index is null. As I have gone through the debugger it appears that my original array is not being copied over properly but I am not sure what I should try next. Thanks in advance.
This is my constructor:
public CandidateList(){
candidates = new String[0];
}
public CandidateList(String[] candidates){
this.candidates = new String[candidates.length];
CandidateList candidateList = new CandidateList();
There is a lot that can be improved in your code, let me add some comments
public void add(String candidate){
//if candidate is actually null you are calling null.equals
//which means this will always result in a NullPointerException
//you can remove this if if you want
if (candidate.equals(null)){
throw new RuntimeException();
}
...
//think about what you are doing here,
//you are setting this.candidates to a new empty array
//(is big contenders.length, but still empty)
this.candidates = new String [contenders.length];
Second part:
public String get(int index){
//you are missing an '=' in index >= candidates.length
if (index < 0 || index > candidates.length) {
throw new RuntimeException("Your argument was not within bounds.");
}
//this for loop is wrong, you are changing 'i' but never use it..
//just return candidates[index] like you said before.
//It was probably null because of the error above
for (int i = index; i < candidate.length(); i++){
candidate = candidates[index];
}
return candidate;
A note on the RuntimeException(RE): if you catch a NullPointerException (NPE) and throw a RE you are actually losing information (since NPE is a more specific error rather than RE). If you want to catch/throw put at least a significant message like "candidate cannot be null"
Let's now analyze the constructor:
public CandidateList(){
candidates = new String[0];
}
public CandidateList(String[] candidates){
// you are doing the same error as above here:
// when you do this you create an EMPTY list of size candidates.lenght
// correct code is this.candidates = candidates
this.candidates = new String[candidates.length];
// this is not necessary, constructors don't need to return anything,
//here you are just creating a new instance that will not be used anywhere
CandidateList candidateList = new CandidateList();
Constructors create objects, they don't return data. I suggest you to take a look at this question Does a Java constructor return the Object reference? and in general read a bit more about constructors
I have a question regarding the arrays..
Suppose that I have an object (A) which contains an array of unknown size, and I don't have any access to the array size or the array itself , however I can apply the following methods on the object A:
empty
full
add(after the last element)
remove(the last element; this returns the element removed)
How can I know the size of the array ??
first call add till the Array is full, then remove and count how many times you removed till the Array is empty, you have the size, like this:
SomeArray a = ...
SomeThingThatArrayCanStore something = ...;
while (!a.full()) {
a.add(something);
}
int size = 0;
while (!a.empty()) {
a.remove()
size++;
}
// here you have the size
You don't need full: that's a red herring.
Here's a solution that achieves this without explicitly creating a temporary container. Essentially I'm using the stack frames to build a container of removed elements.
If A is the type of the array, and a the instance, and the remove() function returns the object removed, then
int size(int n, A a){
if (a.empty()){
return n; // all done, n holds the number of elements removed
}
Object o = a.remove(); // pop the element
int ret = size(n + 1, a); // call self with the array truncated
a.add(o); // push the element back
return ret;
}
is one way, if you call it initially with n set to zero. It's ruinously expensive when it comes to the creation of stack frames, but has a strange elegance to it.
Try something fun with reflection : Reflection allow you to acces private field and unknown field. It is like dark magic : powerfull but dangerous !
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.List;
public class ArrayFinder {
public void printAllArraysLength(A a) throws IllegalArgumentException, IllegalAccessException {
for (Field field : A.class.getDeclaredFields()) { // get all private fields
field.setAccessible(true); // private are now public !
Object array = field.get(a); // get the field content.
try{
System.out.println(field.getName() + " length : " + getArrayLenth(array));
}catch(Exception e){
System.out.println(field.getName() + " is not an array");
}
}
}
private int getArrayLenth(Object array) {
Class arrayClass = array.getClass().getComponentType();
if(arrayClass == null){
// no component type, maybe a list.
return ((List) array).size();
}
else {
if (arrayClass.isPrimitive()) {
return Array.getLength(array);
}else{
return ((Object[]) array).length;
}
}
}
}
Ok, that's probably not what your teacher expect you to do with add / remove / empty and full.
I am making an implementation of the ArrayList class from scratch, using just Object[] and the standard functions. I'm trying to make a "size" method, which returns an int that is the size of the Object[] array.
public class MyArraryList{
Object[] Objects = new Object[0];
public int sizeOf(Object[] o)
{
int i = 1;
while(i > 0)
{
if()
}
}
This is what I have so far. In the if statement, I essentially want to check if there's an error along the lines of "index out of range of array". I'm not sure what the syntax for this is. Can someone explain how to do this please? thanks!
You can find the length of an array using
objects.length
It would be possible to write a version of ArrayList where the length of the array is always equal to the size of the list. In this case the size method would just be
public int size() {
return objects.length;
}
Such a list would be very slow. Because arrays are fixed-length, you would have to create a new array on every addition or removal for this to work.
ArrayList does not work like this. An ArrayList has 2 fields; an Object[] and an int called size. The point is that the length of the array is often higher than the size of the list, because there are unused slots at the end of the array. If you do it this way the size method is just
public int size() {
return size;
}
The most useful thing you can do is read the source code for ArrayList to see how it works.
I essentially want to check if there's an error along the lines of "index out of range of array"
You can find the length of an array like this:
int length = 0;
try {
while (true) {
Object o = objects[length];
length++;
}
} catch (ArrayIndexOutOfBoundsException e) {
// ignore
}
However you should not use exceptions in such a way. They should be reserved for genuinely exceptional situations.
you could use a try catch with ArrayIndexOutOfBoundsException e, which was made for these kinds of instances.
http://www.tutorialspoint.com/javaexamples/exception_multiple1.htm
public class StudentSchedular {
private Student[] students=new Student[10];
private int counterStudent;
public String addStudent(int rollNumber,String name)
{
students[counterStudent++]=new Student(rollNumber,name);
return "Student added successfully";
}
public void showAllStudents()
{
for(int i=0;i<students.length;i++){
System.out.println(students[i].getRollNumber());
System.out.println(students[i].getName());
}
}
}
I know this is a noob question..but still !
Here I have omitted the other getter/setter parts and other cases where I input the values for rollnumber and name. I am trying to print the object array, but it is giving an null pointer exception. I am inputting only 2 3 values and when I try to print, it gives NPE. I know this is because of null values being in the remaining index positions, I just needed a soln to print the whole object array !
The reason why you get NullPointerException is because of private Student[] students=new Student[10];. It means that you have an Student array which has a fixed size of 10. Default Object values in Java is null. Without adding anything to the array it means you have 10 null objects in students.
If an offset in the students array is not filled yet, you will hit a null value and get an exception, because you try to invoke a method on null.
You can validate it in the loop:
for(int i=0;i<students.length;i++){
if(students[i] instanceof User) {
System.out.println(students[i].getRollNumber());
System.out.println(students[i].getName());
}
}
EDIT: This 'issue' can be avoided by using List<User> instead of User[]. But I can't decide for you if it makes more sense.
I prefer the new For loop (since Java 5).
for(Student student : this.students) {
}
The new for loop works for arrays and all iterables objects, like ArrayList. You'll get only non-null objects.
For answer your question, the best practice is:
Overriding toString() in your Student Object.
#Override
public void String toString(){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(this.rollNumber);
stringBuilder.append(this.name);
return stringBuilder.toString();
}
And at your loop, just do
System.out.println(stundents[i]);
println handles null values as you want, and code turns clean.
Your array has 10 slots. If 3 are given values, then you have 7 slots with null. You will need to either change the type of data structure you are using, or check for nulls when printing. The below code would do a null check and then print which index in the array contains the null value.
public void showAllStudents()
{
for(int i=0;i<students.length;i++)
{
if(students[i] != null) {
System.out.println(students[i].getRollNumber());
System.out.println(students[i].getName());
}
else
{
System.out.println("Array is null at index: " + i);
}
}
}