views:

304

answers:

6

Note: Following is my homework/assignment, feel free not to answer if you will.

I want to delete/remove an element from an String array(Set) basic, I'm not allowed to use Collections..etc.

Now I have this:

void remove(String newValue) {

            for ( int i = 0; i < setElements.length; i++) {
               if ( setElements[i] == newValue ) {
                    setElements[i] = "";

               }
            }

       }   

I does what I want as it remove the element from an array but it doesn't shorten the length. The following is the output, basically it remove the element indexed #1.

D:\javaprojects>java SetsDemo
Enter string element to be added
A
You entered A
Set size is: 5
Member elements on index: 0 A
Member elements on index: 1 b
Member elements on index: 2 hello
Member elements on index: 3 world
Member elements on index: 4 six
Set size is: 5
Member elements on index: 0 A
Member elements on index: 1
Member elements on index: 2 hello
Member elements on index: 3 world
Member elements on index: 4 six

lupin

+1  A: 

Basically you need to create a new array which is as long as the old array's length minus 1 and then you need to copy the valid elements from the old to the new array in a loop and then replace the old array with the new array.

Since this is homework, details are left away. Feel free to post a comment for a bit more clarification.

BalusC
A: 
void remove(String newValue) {
    if(setElements.length == 0) return;
    String [] array = new String[setElements.length-1];
    int j = 0;
    for ( int i = 0; i < setElements.length; i++) {
       if ( setElements[i] != newValue ) {
            array[j++] = setElements[i];
       }
    }
    setElements = array;
}
sza
You probably meant to set `setElements` to `array` at the end, rather then the other way around.
Jonathan M Davis
What happens if `newValue` is not in the array? (Result: `IndexOutOfBoundsException`). Second, what if there are multiple entries matching `newValue`? (Result array has `null` elements at the end)
Kevin Brock
@Kevin Brock: array[j] will not be evaluated if newValue is not in the array even j is 1 larger.
sza
@Siegfried: If it is not in the array then the code will attempt to copy all the elements from the old array but the new array is one element smaller than the old one so the last element will not fit. So, yes, array[j] is evaluated for every element in `setElements`.
Kevin Brock
+1  A: 

All that setElements[i] = ""; does is change the value of an element in the array. It does not actually remove anything from the array. If you were using a collection class and called remove(i) on it, then you would actually be removing that element from the collection. But here, you're just changing its value. However, arrays in Java have a fixed size and cannot be resized, so there is no way to remove elements from them. The solution, therefore, is to create a new array with a length one shorter than the old one, and then copy all of the values that you want to keep into the new one. So,

  1. Create new array with a length of setElements.length - 1.

  2. Copy all of the elements in setElements into the new array, except for the one which you're looking to remove. Be careful of the fact that the indices into the two arrays will be off by one rather than equal once you've reached the index for the element that you wish to remove.

  3. Set setElements to the new array if you want to keep using the same variable for your array.

Jonathan M Davis
+1  A: 

The size of an array in Java can't be changed once the array is created. The following links should help you with transferring the existing items to a new array :-)

See: System.arraycopy and Array.copyOf(*).

pst
The "of course" may not be known to a student. There do exist languages where arrays can be resized...
masher
It can be interesting explaining stuff to students, since it can be very suprising what they do or do not know. Heck, sometimes it's surpising what "seasoned pros" do and do not know. Though generally, if they're worth their salt, what they don't know is very different from what a student doesn't know.
Jonathan M Davis
@masher Thank you for the insight. I've updated the post.
pst
+3  A: 

You can't change the length of an array object once it's created. Here's an excerpt from JLS 10.2. Array Variables:

Once an array object is created, its length never changes. To make an array variable refer to an array of different length, a reference to a different array must be assigned to the variable.

This means that for this problem, you'd have to allocate a new array that's one-element shorter than the original array, and copy over the remaining elements.

If you need to remove element at index k, and the original array has L elements, then you need to copy over elements (upper bounds are exclusive):

  • From [0,k) to [0,k) (k elements)
  • From [k+1,L) to [k,L-1) (L-k-1 elements).
  • For a total of L-1 elements copied

static String[] removeAt(int k, String[] arr) {
    final int L = arr.length;
    String[] ret = new String[L - 1];
    System.arraycopy(arr, 0, ret, 0, k);
    System.arraycopy(arr, k + 1, ret, k, L - k - 1);
    return ret;
}
static void print(String[] arr) {
    System.out.println(Arrays.toString(arr));       
}   
public static void main(String[] args) {
    String[] arr = { "a", "b", "c", "d", "e" };
    print(arr); // prints "[a, b, c, d, e]"

    arr = removeAt(0, arr);
    print(arr); // prints "[b, c, d, e]"

    arr = removeAt(3, arr);
    print(arr); // prints "[b, c, d]"

    arr = removeAt(1, arr);
    print(arr); // prints "[b, d]"

    arr = removeAt(0, arr);
    arr = removeAt(0, arr);
    print(arr); // prints "[]"
}

This uses System.arraycopy; you can always write your own if this isn't allowed.

static void arraycopy(String[] src, int from, String[] dst, int to, int L) {
    for (int i = 0; i < L; i++) {
        dst[to + i] = src[from + i];
    }
}

This is a simplistic implementation that doesn't handle src == dst, but it's sufficient in this case.

See also


Note on == for String comparison

Most of the time, using == to compare String objects is a mistake. You should use equals instead.

String ha1 = new String("ha");
String ha2 = new String("ha");
System.out.println(ha1 == ha2); // prints "false"
System.out.println(ha1.equals(ha2)); // prints "true"

See also

polygenelubricants
so much for homework.
GregS
A: 

Thanks all for the helpful reply, especially to polygenelubricants, for a great example of arraycopy, and all those helpful tips. This can be close.:)

lupin
It doesn't have to be closed, but you can accept an answer to show that the question has been satisfiably answered.
polygenelubricants