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.
Related
I want to populate an array that I have in my method with elements that I receive as parameters to my method. I cannot use any methods from predefined classes such as Arrays or Collections
Example:
In my main method in my main class I have:
ClassB obj = new ClassB obj ();
obj.addElement(objD1);
obj.addElement(objD2);
What I expect in my method addElement (B Class):
public void addElement(ClassD element){
ClassD[] array = new ClassD[10];
and then how do I populate?
A for loop? Two for loops?
End result I want:
array[0] = objD1;
array[1] = objD2;
The question is not really clear. If my understanding is correct you want to define your ClassB like:
public class ClassB {
private ClassD[] array = new ClassD[10];
private int index;
public void addElement(ClassB element) {
array[index++] = element;
}
}
The code you're asking for is probably array[index++] = element. Here we insert the element inside array in position index and then we increment index (using the post-increment operator ++).
There are few problems with this implementation, though. First of all you can't add more than 10 elements. Adding the 11th element will result in a ArrayIndexOutOfBoundsExcepiton. I would suggest to manage the exception and throw something more descriptive like:
public void addElement(ClassB element) {
if (index >= array.length) {
throw new TooManyElementsException();
}
array[index++] = element;
}
Where TooManyElementsException is simply defined as:
public class TooManyElementsException extends RuntimeException {
}
EDIT
Following your comment, I can slightly modify the addElement() method and get there.
public void addElement(ClassB element) {
int index = 0;
while (index < array.length && array[index] != null) {
index++;
}
if (index >= array.length) {
throw new TooManyElementsException();
}
array[index] = element;
}
The whole thing works because Java always sets all the elements to null when you create a new array. So, every time we start from 0 and we look for the first null position; then, we put our element there.
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'm trying to iterate over an Object array. Using the next() method works so I'm guessing that my iterator class and constructors are working.
For some reason i'm not getting any output while the hasNext() method is running.
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
With "hej" being my Object array.
My code for the next(); and hasNext() methods are as follows:
public class StackIterator implements Iterator<Object>{
// fields
private int element = 0;
private final Object[] elements;
private final int max;
// constructor
public StackIterator(Object[] values, int maxIndex) {
elements = values;
max = maxIndex;
}
// methods
public boolean hasNext() {
return element < max;
}
public Object next() {
return elements[element++];
}
}
The file that constructs the Object Array and the Object Array depends on an interface:
public interface Stack {
int size();
boolean isEmpty();
void push(Object element);
Object pop();
Object peek();
Iterator<Object> iterator();
}
The methods are then explained in another file:
public class StackExample implements Stack {
// fields
int length = 0;
Object[] arr;
// constructor
public StackExample() {arr = new Object[length];}
// method returns size of object array
public int size() {
return arr.length;
}
// method checks if object is empty
public boolean isEmpty() {
boolean result = false;
if (arr.length == 0){
result = true;
}
return result;
}
// method for push
public void push(Object element) {
newBiggerObj();
arr[0] = element;
}
// returns the first object of the stack
public Object pop() {
Object[] temp = new Object[arr.length-1];
Object first = arr[0];
for (int i = 0; i<arr.length-1; i++){
temp[i] = arr[i+1];
}arr = temp;
return first;
}
// returns the object on top of stack
public Object peek() {
if (isEmpty()){
try{
throw new Exception("Stack empty, can't peek!");
}
catch(Exception e){
return e.getMessage();
}
}
else {
Object first = arr[0];
return first;
}
}
// method for push method
private void newBiggerObj(){
Object[] temp = new Object[arr.length+1];
for (int i = 0; i<arr.length; i++){
temp[i+1] = arr[i];
}
arr = temp;
}
public String toString(){
String str = "";
for (int i = 0; i < arr.length; i++){
str = str + arr[i] + " , ";
}return str;
}
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
}
What bothers me is that the method Iterator is within itself returning an instance of the class Stack Iterator. Which i posted above. So my real problem seems to be that my fields are not being given any value, since I am not myself giving the any values within the constructor.
My main method in which I'm testing all of this is as follows:
public class Teststack {
public static void main(String[] args){
// new instane of class StackExample
StackExample hej = new StackExample();
// test for the different methods
System.out.println(hej.isEmpty());
System.out.println(hej.size());
hej.push(4);
hej.push("hej");
hej.push(6);
hej.push(5);
System.out.println(hej.size());
System.out.println(hej.peek());
System.out.println(hej.pop());
System.out.println(hej.toString());
System.out.println(hej.isEmpty());
System.out.println("Testing Iterator: ");
// test for iterator
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
}
}
In your StackExample class, I don't see the length variable being updated when elements are pushed or popped. Due to this, length will always be 0 and calls to it.hasNext() will always return false.
You don't need to pass the length as a separate argument. You can find the array's length in the StackIterator constructor and use it.
Also note that since you're creating a new array on every push and pop, the iterator returned by StackExample#iterator() will become stale after every push/pop since it will work on an old copy/state of the stack.
The problem is here:
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
length field is never changed, so its value is always 0. You can change the code to this:
public Iterator<Object> iterator() {
return new StackIterator(arr, arr.length);
}
Also, before retrieving elements from the iterator, you should always call it.hasNext. The fact you did this:
Iterator it = hej.iterator();
Object j = it.next();
And worked was just pure luck.
Apart of this, I can sense you have a bad design on your stack implementation. Here are some hints to improve your code:
The inner array should be initialized with a default size different than 0. E.g. 10 (as done in java.util.ArrayList implementation).
You should avoid creating a new array when adding (push) or removing (pop) an element from your stack. Instead of this, you should use the length field to control how many elements are in your stack.
The value of the new size should be based on another formula rather than array.length + 1. For example, try using something like int newSize = array.length / 2 * 3;.
Resize the inner array only when necessary. When calling push, do it only if you precisely need to increase the size of the array. When calling pop, do it if the current length of the array (this is, array.length) is far greater than the value of length field of your class.
Never forget to update the value of length on push and pop methods.
Couple of issues:
You are calling Object j = it.next(); after creating iterator and then check for hasNext. You are incrementing the element index. Hence if you just have one element, you wont enter the while loop. In addition, if your custom datastructure is empty i.e. array has no elements then you are prone to ArrayIndexOutOfBoundException.
You will always iterate and print n-1 elements instead to n elements.
Once you iterated, then your pointer will always point to last element and never get resetted. So very next time you wont be able to iterate over your elements. Its a one time iterator.
Try not to call
Object j = it.next() statement, but just while cycle. Seems you have an array of just 1 element.
There are a number of problems with this code:
In the StackIterator constructor there is no bounds checking on maxIndex. Callers can pass in a number greater than values.length, less that 0, etc.
In the next method, there is no check of the end condition, either directly or by calling hasNext(). Callers can keep calling next() and see elements beyond max or even get an ArrayIndexOutOfBoundsException, when they should be getting a NoSuchElementException.
The Stack class never increments or decrements its length field when elements are pushed or popped.
The Stack class tracks the length separately from the array, even though it always resizes the array on every push or pop, but Java arrays already know their size. (But see the next item.)
The Stack class resizes the array on every push or pop, which is very inefficient. Typically classes like this only resize the array when necessary, allowing 'slack' space, to give amortized constant time performance (see ArrayList). If you do this, however, it is necessary to null out popped items to avoid unintentional object retention.
The Stack adds and removes elements at the beginning of the array. This is incredibly inefficient since it means a O(n) reshuffling must be done on every push or pop.
The peek() method takes into account the possibility that the Stack may be empty, but the pop() method does not. A pop() on an empty Stack will throw an ArrayIndexOutOfBoundsException.
Stack is not a generic class. It holds Object. Users of the Stack will have to cast the return values from peek() or pop(), and it isn't type safe. In your example, you show a stack that is a heterogeneous mixture of String and Integer. This is a very Java 1.2 way of doing things, and while it isn't necessarily wrong, you should consider parameterizing Stack.
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.
I am working on a Linked Lists assignment for my OOP class, and have run into some trouble with a remove method. Our professor has asked us to write a method:
public Object removeElement(int index)
This takes an index, which is the location of the element that needs removed. It must return the data the deleted node contained as well. However, I am having trouble with getting the method to return the object it is removing. For some reason I keep getting the error that the method must return a result of type object. I have it returning an object, and I've gone through trial and error in various spots with no success.
Here is my code:
public Object removeElement(int index)
{
ListIterator iterator = listIterator();
Object object;
//If the supplied index is less than zero, throw an exception.
if(index < 0)
{
IndexOutOfBoundsException ex = new IndexOutOfBoundsException();
throw ex;
}
else
{
for(int i = 0; i <= index; i++)
{
if(!iterator.hasNext())
{
IndexOutOfBoundsException ex = new IndexOutOfBoundsException();
throw ex;
}
else
{
if(i == index)
{
object = iterator.next();
iterator.remove();
return object;
}
else
{
iterator.next();
}
}
}
}
}
You have it returning an object if i == index. But the compiler doesn't know that the loop will actually always end at that point. It's looking at the bottom of the loop and thinking "What do we want to return if we get here?"
I would actually restructure your code to:
if (index < 0)
{
// No need for a separate variable
throw new IndexOutOfBoundsException();
}
// No need for an else block
ListIterator iterator = listIterator();
Object current = null;
for (int i = 0; i <= index; i++)
{
// Note: assuming you expose the size(), you could check this up front...
if(!iterator.hasNext())
{
throw new IndexOutOfBoundsException();
}
current = iterator.next();
}
iterator.remove();
return current;
Now you always call remove and return when you've called next() the given number of times, because that's when the loop will end other than via an exception.
Firstly do not use iterator from java LinkedList it is Doubly linked list , I think professor wants to see how you implement remove functionality for LikedList data structure.
Secondly make loop and condition where i+1 == index in this place, save current element for return like Node returnElement = curent.next; and make delete manipulation curent.next = curent.next.next;
Pls post listIterator() method implementation and the error message that you are getting.
Note:> You have to manage the size of the list using an class variable such as an integer. So you dont have check !iterator.hasNext(), instead compare index with current size.