views:

123

answers:

7

I recall seeing, somewhere, an example that stepped through String args[] by deleting the lowest numbered value(s)

public static void main( String args[]) {
    while (args.length > 0 ) {
    // do something and obliterate elements from args[]
    }
}

Obviously, a variable tracking current position in args and compared to args.length will do it; or an ArrayList made from args[]'s contents, with argsAL.size(). Am I mis-remembering an ArrayList example? I know this is a borderline question, the likely answer is, "No, there isn't and there shouldn't be either!". Maybe I'm over-focused...

Bill

+4  A: 

No, there isn't and there shouldn't be either! Deleting from the front of an array would be a needlessly expensive way to do this.

You might be thinking of many scripting languages having a shift operator to dequeue the next element (perl, bash, etc).

Edit: Just for posterity, here's a pretty simple implementation of Queue that would allow you to "fake" the same functionality (i.e. encapsulate the cursor):

class ArrayQueue<E> extends AbstractQueue<E> {

    private int cursor = 0;
    private final E[] data;

    public ArrayQueue(E[] data) {
        this.data = data;
    }

    private boolean inRange() {
        return cursor < data.length;
    }

    @Override
    public E peek() {
        return inRange() ? data[cursor] : null;
    }

    @Override
    public E poll() {
        return inRange() ? data[cursor++] : null;
    }

    @Override
    public boolean offer(E e) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void clear() {
        cursor = data.length;
    }

    @Override
    public Iterator<E> iterator() {
        //ommitted for brevity
    }

    @Override
    public int size() {
        return data.length - cursor;
    }

}

Usage:

public static void main(String[] args) throws Exception {
    Queue<String> argQ = new ArrayQueue<String>(args);
    String command = argQ.poll();
    String target = argQ.poll();
}

Warning: Untested

Mark Peters
+1 That's my perception too.
OscarRyz
Somebody let me know why you downvoted so I can improve my answer. Anonymous downvotes are cowardly.
Mark Peters
Nice, if it has to be done, this or the for loop from Ben S. are the way to go.Thanks, folks!Bill
Bill IV
ps - agree w/ Mark about downvotes. Constructive review is golden. its hard to learn from -1.
Bill IV
+1  A: 

Just use a for loop, except when you really love arraycopy's.

From a performace view it doesn't matter either, most command lines don't except more than 32k chars and I don't think your app is usually used for 16k args on the command line.

Daniel
A: 

You should really use a List, perhaps using java.util.Arrays.asList(args). Then you have ordered traversal and easy removal of front and back elements.

Platinum Azure
That method returns an `ArrayList`, which means that popping elements off the front will cause an array copy of all other elements to move them up in the array. Far from ideal.
Ben S
technically this gives you an ArrayList which has O(n) performance for removal at front... but the args[] array is small enough that performance doesn't matter.
Jason S
Ack! Good point, that's what I get for not reading the docs. Shame on me! I think using some sort of LinkedList constructor with the array would be the way to go, then.
Platinum Azure
While I wasn't the person who downvoted you, I really think that you (and the people who commented above) should really test your answers first. `Arrays.asList()` does *not* return an `ArrayList`, and if you call `remove()` on it, you'll get an exception.
kdgregory
+2  A: 

If you plan on popping off elements, don't use an array list since the whole array will need to be copied a bunch of times. Instead, do something like this:

public static void main(String args[]) {
    for (String arg : args) {
        // consume arg somehow
    }
}
Ben S
I'd suggest the enhanced for-loop. Then you can ignore the fact that you're looking at an array.
Mark Peters
Good point, edited.
Ben S
@Mark - if your argument syntax uses "--xx" style options, then old-school for loops may be more convenient
Stephen C
@Stephen C: That's a good point. Though in that case I'd still try to avoid the index cursor and use an Iterator explicitly. With that level of complexity I think some of the others are right in suggesting a library for argument support.
Mark Peters
+1 for suggesting using a `for` loop (although I agree that an indexed `for` would be a better idea) rather than trying to replicate an idiom from another language.
kdgregory
... although really, is the cost of popping elements going to be that high? (and to answer: I found that you'd have to have 100,000 elements before a `LinkedList` won ... and it's much more space-inefficient)
kdgregory
+1  A: 

...Am I mis-remembering an ArrayList example?..

Probably or some other programming language.

Some of them have the method shift which when invoked does that, gives you the 0th element and removes it, something like:

main( args: Array[String) {
    name = args.at(0)
    args.shift
    lastName = args.at(0)
    args.shift
}
OscarRyz
I'm sure that's it. Thanks.
Bill IV
+1  A: 

It would be a weird way to do it. Technically more expensive, but unless you have some crazy big command line, that really isn't even a consideration.

It has been suggested already to use a loop and this can definitely work.

For better control of command line options check out java-getopt.

LanceH
Why was this downvoted?
Mark Peters
+3  A: 

You should really use an argument parser. My favorite is Java Simple Argument Parser (JSAP). There is no reason to manipulate the args[] array directly. I use JSAP even for the most basic command line programs, because eventually they aren't "basic" anymore.

fuzzy lollipop
I'll look for it. Thanks. "basic" programs have a funny way of growing... they say you really know an organization by how it behaves in a crisis, but "trivial" and "basic" programs are probably second closest to the core.
Bill IV