So I had to use an array to add Aliens into my program, and now I am supposed to move all the parts that are "null" to the front, so instead of printing out Alien 1: blah blah, Alien 2: null, Alien 3: null, Alien 4 blah blah, I need it to have Alien 1 blah blah, Alien 2 blah blah.
I know how to do the remove feature in an array list, but am not sure how to figure this out with just a simple array.
public void consolidate() {
for (int index = 0; index < cockpitCrew.length; index++) {
if (cockpitCrew[index] == null) {
}
}
}
This is the code I have so far for the "removal" of the null array objects.
EDIT: Basically I need it to skip over the nulls when it prints out in this loop
Inside your if statement, you just need to find the first non-null array element starting at that spot (you'll need a loop for that) and then write some code to swap positions of those elements.
If you don't find a non-null array element, you can safely terminate your loop.
One thing you could do is create another array and add the objects to it.
Keep two indexes rear and front. When you meet a null object add it to rear, when you meet a not null object add it to front. Thus at the end you will have null objects at the rear of the array and not null objects at the front of the array.
public void consolidate() {
Alien newAlienArray[] = new Alien[cockpitCrew.length];
int front = 0;
int rear = cockpitCrew.length - 1;
for (int index = 0; index < cockpitCrew.length; index++) {
if (cockpitCrew[index] == null) {
newAlienArray[rear] = cockpitCrew[index];
rear--;
} else {
newAlienArray[front] = cockpitCrew[index];
front++;
}
}
cockpitCrew = newAlienArray;// if you finally need to replace the new order in cockpitCrew
}
I don't quite understand your approach, but here is how I would solve this problem...
// Make it static, let's not rewrite the Array in place...
public static Alien[] consolidate(Alien[] cockpitCrew) {
List<Alien> al = new ArrayList<Alien>(); // Create a List to hold the Alien(s).
for (Alien alien : cockpitCrew) { // Use a for-each loop over the cockpitCrew.
if (alien != null) { // Test for null.
al.add(alien);
}
}
return al.toArray(new Alien[al.size()]); // Return a new Array.
}
There is different method to solve this problem:
You can use the same array
in the same array is similar a "bubble sorting", if "cockpitCrew[index] == null" change it with the next array element, for this you can use 2 index. First index for current element e second index for the next and eventually a swap variable.
You Can use 2 different array
this is very simple method, if (cockpitCrew[index] <> null), you copy this element (not null) in the 1st array otherwise "cockpitCrew[index] == null" copy it at the 2nd array .
I think that is not very difficult.
Related
I have written this method to remove a value (the account from the accounts array).
public boolean removeAccount(BankAccount accountNumber){
for(int i = accounts.length - 1; i >= 0; i--) {
if(accounts[i] == accounts.length+1) {
accounts.length;
}
return -1
}
Would this be a proper way to remove an element from an array?
The code you are using to remove element is wrong. Also, I would recommend you to use List.Since if you remove an element from array you will need to change the index to -1 for all the elements that comes after the removed element. Also, array will have a blank value which will cause problems.
Updating your code to List. It should be something like this -
public void removeAccount(BankAccount accountNumber,ArrayList accounts)
{
int length = accounts.size();
for(int i = 0; i<length; i++)
{
if(accountNumber.equals(accounts.get(i))) //*
{
accounts.remove(i);
break;
}
}
}
In you code you never compare the objects. you are comparing an object with integer.
Also, In your code at the first iteration of loop method will return -1.
You call accounts.length in each iteration two times. I don't think it is a good practice. You should store the length in a variable and use it.
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.
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));
}
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.
I am trying to delete an element from an array depending on the method's argument. If the argument is the last element's position, I can't use the for loop and end up specifying an if statement just to satisfy that. Also trying to return the current name in that position after the deletion. I have tested and the following code works.
I am trying to see if there is a better way of producing the same result without the extra if statement. I tried looking up the Arrays Class and no static method there that seems to help either. Please advice if there is a better way of doing this method. Thanks.
public class ArrayTester {
public static String[] array1 = new String[100];
public static void main(String[] args) {
remove(50);
System.out.println(remove(50));
}
public static String remove(int name) {
if(name == 99){
array1[name] = null;
return array1[name];
}
else if (name >= 0 && name < 99){
for (int i=name; i < array1.length-1; i++){
array1[i] = array1[i+1];
}
return array1[name];
}
return null;
}
}
And with ArrayList??
import java.util.ArrayList;
public class RemoveArrayListElement {
public static void main(String[] args) {
ArrayList<String> arlist=new ArrayList<String>();
//<E> it is return type of ArrayList
arlist.add("First Element"); // adding element in ArrayList
arlist.add("Second Element");
arlist.add("Third Element");
arlist.add("forth Element");
arlist.add("fifth Element");
// remove array list element by index number
arlist.remove(3);
// remove ArrayList element by Object value
arlist.remove("fifth Element");
// get elements of ArrayList
for(int i=0;i<arlist.size();i++)
{
System.out.println("ArrayList Element "+i+" :"+arlist.get(i));
}
}
}
Output:
Remove ArrayList Element 0 :First Element
Remove ArrayList Element 1 :Second Element
Remove ArrayList Element 2 :Third Element
With ArrayList is easier, isn't it?
You can simplify your code a little by excluding the if. Unfortunately, the loop has to stay - arrays provide contiguous storage, so you need to move the data if you are to delete an item in the middle of the array.
public static String remove(int index) {
// Note the use of "index" instead of "name"
if (index < 0 || index >= array1.length) {
// A more common approach is to throw an exception,
// but your code returns null for out-of-range index
return null;
}
for (int i = index; i < array1.length-1 ; i++) {
array1[i] = array1[i+1];
}
// Unconditionally set null in the last element of the array
array1[array1.length-1] = null;
return array1[index];
}
Looking at your code, you seem to want something like this -
if (name == 99) {
try {
return array1[name];
} finally {
array1[name] = null;
}
}
array1 = Arrays.copyOf(array1, 99);
Sounds to me like you would be better off using an ArrayList. Arrays aren't really made for what you're doing. But you could also just null the value at the desired location and run the java.util.Arrays.sort method on the array. Something like this (I'm winging it, but this would be close):
public static String remove(int name) {
String returnValue = array1[name];
array1[name] = null;
java.util.Arrays.sort(array1);
return returnValue;
}
This is going to leave you with a sorted array, but you're already shifting them out of their original indices anyway so that may or may not matter to you.
Another option would be to simply add a if (array1[index] != null) conditional to all of your code handling that array. That way you wouldn't have to shift your values around in the array and your code would just skip over any null values it runs into.