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.
Related
I'm sitting on an assignment for university and I'm at a point, where I fear I haven't really understood something fundamental in the concecpt of Java or OOP altogether. I'll try to make it as short as possible (maybe it's sufficient to just look at the 3rd code segment, but I just wanted to make sure, I included enough detail). I am to write a little employee management. One class within this project is the employeeManagement itself and this class should possess a method for sorting employees by first letter via bubblesort.
I have written 3 classes for this: The first one is "Employee", which contains a name and an ID (a running number) , getter and setter methods and one method for checking whether the first letter of one employee is smaller (lower in the alphabet) than the other. It looks like this:
static boolean isSmaller(Employee source, Employee target) {
char[] sourceArray = new char[source.name.length()];
char[] targetArray = new char[target.name.length()];
sourceArray = source.name.toCharArray();
targetArray = target.name.toCharArray();
if(sourceArray[0] < targetArray[0])
return true;
else
return false;
}
I tested it and it seems to work for my case. Now there's another class called EmployeeList and it manages the employees via an array of employees ("Employee" objects). The size of this array is determined via constructor. My code looks like this:
public class EmployeeList {
/*attributes*/
private int size;
private Employee[] employeeArray;
/* constructor */
public EmployeeList(int size) {
this.employeeArray = new Employee[size];
}
/* methods */
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
/* adds employee to end of the list. Returns false, if list is too small */
boolean add(Employee m) {
int id = m.getID();
if (id > employeeArray.length) {
return false;
} else {
employeeArray[id] = m;
return true;
}
}
/* returns employee at certain position */
Employee get(int index) {
return employeeArray[index];
}
/* Sets employee at certain position. Returns null, if position doesn't exist. Else returns old value. */
Employee set(int index, Employee m) {
if (employeeArray[index] == null) {
return null;
} else {
Employee before = employeeArray[index];
employeeArray[index] = m;
return before;
}
}
Now comes my real problem: In a third class called "employeeManagement" I am supposed to implement the sorting algorithm. The class looks like this:
public class EmployeeManagement {
private EmployeeList ml = new EmployeeList(3);
public boolean addEmployee(Employee e) {
return ml.add(e);
}
public void sortEmployee() {
System.out.println(ml.getSize()); // I wrote this for debugging, exactly here lies my problem
for (int n = ml.getSize(); n > 1; n--) {
for (int i = 0; i < n - 1; i++) {
if (Employee.isSmaller(ml.get(i), ml.get(i + 1)) == false) {
Employee old = ml.set(i, ml.get(i + 1));
ml.set(i+1, old);
}
}
}
}
The "println" before my comment returns "0" in console... I am expecting "3" as this is the size I gave the "EmployeeList" as parameter of the constructor within my "EmployeeManagement" class. Where is my mistake ? And how can I access the size of the object I created in the "EmployeeManagement" class (the "3") ? I'm really looking forward to your answers!
Thanks,
Phreneticus
You are not storing size in your constructor. Something like,
public EmployeeList(int size) {
this.employeeArray = new Employee[size];
this.size = size; // <-- add this.
}
Also, setSize isn't going to automatically copy (and grow) the array. You will need to copy the array, because Java arrays have a fixed length. Finally, you don't really need size here since employeeArray has a length.
The size variable you are calling is the class field. If you take a quick look at your code, the getter is getting the field (which is initialized as zero when created). The size you are using it. The good way of doing it would be to get the size of the array in the getter like this:
public int getSize() {
return employeeArray.length;
}
This would return the size of the array in the object.
I have a method which needs to add the provided bank account to an array which I have created:
public boolean addAccount (BankAccount newAccount[]) {
if (numAccounts == 0) {
return false;
}
else {
return true;
for(int counter=0; counter<newAccount.length; counter++)
newAccount[counter] += accounts;
}
}
it is tested by this method:
public static boolean test5() {
System.out.println("Test5: add an account to a customer.");
BankAccount b = new BankAccount();
Customer c1 = new Customer("Alice", "Smith");
customerCounter ++;
if (!c1.addAccount(b))
return false;
return c1.toString().equals("Alice Smith, " + c1.getCustomerID() + "\n" + b.toString() + "\n");
}
However I am getting an error which eclipse does not have a solution for in this line:
newAccount[counter] += accounts;
First of all you need to improve the code quality. Re-design your function and data structure.
In the addAccount function, where did you derive/manipulate 'numAccounts'?
In method parameter, use List instead of array 'BankAccount newAccount[]'. Use like (List accounts). Then you can use accounts.add() method.
what is the definition of 'accounts'?
Do you really need to return anything from this method?
after return statement, no code will be executed. move 'return' statement as the last statement.
Paste the full code to get idea about overall structure.
If u just want to see how a new value can be added to an array then here it is...
int myArray[]={10,20,30};
int newNumber=200; //new value to be added
/*Size of an array doesn't change once it is initialized,so a new Array must be
created (with new Size )to add new values.*/
int newArray[]=new int[myArray.length+1];
//The newArray will have {0,0,0,0};
// Now copy all the data from previous array to new array.
for(int i=0;i<myArray.length;i++)
newArray[i]=myArray[i];
//Now the content of newArray is {10,20,30,0}
newArray[newArray.length-1]=newNumber;
//Now the final content of newArray is {10,20,30,200}.
Now,Having said that, I agree with #Turing85 and #Shafiul.With your above code,you will eventually get unreachable code and also Type Incompatible errors and yes,kindly redesign your code.
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
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
I'm working on sorted Queues like a Priority Queue. I already did it with a List, and it already worked great. Now I'd like to do it with a array. But I have a little logical Problem with add a new Element and insert it into the sorted array.
The final output should be like that:
Priority: 5 Value: x
Priority: 4 Value: iso
.... (and so on)
So the Element with the highest Priorithy should be on index = 0.
I just don't know (and yes I know it's really simply to switch it, but I just can't do it :/) how to do it...
I already tried a few things but I'm stuck... :/ can please anyone help?
Here's my code:
public class Queue {
private QueueElem[] a;
public Queue(int capacity)
{
QueueElem[] tempQueue = new QueueElem[capacity];
a= tempQueue;
}
public void enqueue(int p, String v)
{
QueueElem neu = new QueueElem(p,v);
int i=0;
while(i<a.length)
{
if (a[i] == null)
{
a[i] = neu;
break;
}
i++;
}
}
public void writeQueue()
{
int i=0;
while((i< a.length) && (a[i] != null))
{
System.out.println("Priority: " + a[i].priority + " Value: " + a[i].value);
i++;
}
}
public static void main(String args[])
{
Queue neu = new Queue(10);
neu.enqueue(4,"iso");
neu.enqueue(2,"abc");
neu.enqueue(5,"x");
neu.enqueue(1,"abc");
neu.enqueue(4,"bap");
neu.enqueue(2,"xvf");
neu.enqueue(4,"buep");
}
}//end class Queue
class QueueElem {
int priority;
String value = new String();
public QueueElem(){ }
public QueueElem(int p, String v)
{
this.priority = p;
this.value = v;
}
public int getPrio()
{
return this.priority;
}
public String getValue()
{
return this.value;
}
}
It would be better if you interpreted your array as a max-heap. That is the typical way to implement priority queue.
What you're looking for, if you're trying to maintain a sorted array for your priority queue, is to implement insertion sort (sort of; you don't have an unsorted array to start with. You have an empty array that you simply add to, while maintaining a sorted order). Every time you insert a new element, you will iterate through the array to find the correct spot and then insert it there, after shifting the elment currently at that spot, and everything after it one spot down. Note that this is not as performant as implementing this using a heap, since at worst you have O(n) performance every time you insert, whereas with a heap you have O(logn).
I don't understand why anyone would want to work with raw arrays... especially now that you have implemented it with a List.
If you want to see how to insert an element in a raw array, look in the code of ArrayList, since underneath it uses a raw array. You'll have to move all the elements to right of the insertion point, which you could copy in a loop, or by using System.arraycopy(). But the nastiest part is that you will likely have to create a new array since the array size increases by one when you add an element (it depends if you are using an array that has exactly the size of your data, or a larger array, as is done in ArrayList).