Is there an easier alternative to mimicking the splat operator?

我怕爱的太早我们不能终老 提交于 2019-12-07 02:21:28

问题


I've found it's available in Ruby, but I recognize it from what I've done in Python; the "splat" operator. Long story short, I'm wondering if there's a simpler way to accomplish what I currently am, mimicking what the "splat" operator does.

I made a central method that the rest can call because I realized I have several very similar ones, and they were all doing the same except for a few minor things. Here's the method signature:

private String callScript(String scriptLocation, String... extraArgs) throws Exception {

I want to require at least one argument (the scriptLocation), and then allow any number of extra arguments. What I end up doing with this is creating a ProcessBuilder. My desire is to do something like this:

ProcessBuilder pb = new ProcessBuilder("something", scriptLocation, /* extraArgs */);

But of course, the ProcessBuilder constructor only accepts things like:

  • List<String>
  • String[]
  • String...

So my approach obviously wouldn't work.

My current workaround, which works fine as far as I know, is:

List<String> finalArgs = new ArrayList<String>();
finalArgs.add("something");
finalArgs.add(scriptLocation);
finalArgs.addAll(Arrays.asList(extraArgs));
ProcessBuilder pb = new ProcessBuilder(finalArgs);

(yes, I understand I don't have to use List and could just make a String[])

(and yes, I understand I could loop through extraArgs and add them to finalArgs individually, instead of having to use addAll and Arrays.asList())

(and yes, I know I can make a function that effectively accomplishes my workaround by returning certain arguments combined with variable arguments)

So I guess outside of these last three statements, is there anything that can achieve this?


回答1:


It depends on your definition of simpler, but you could write a class utilizing the Builder pattern:

public class MyProcessBuilder {
    List<String> args;

    MyProcessBuilder( String text, String location ) {
        args = new ArrayList<String>();
        args.add( text );
        args.add( location );
    }

    MyProcessBuilder arg( String arg ) {
        args.add( arg );
        return this;
    }

    MyProcessBuilder args( String... args ) {
        this.args.addAll( Arrays.asList( args ) );
        return this;
    }

    public ProcessBuilder go() {
        return new ProcessBuilder( args );
    }

    public static MyProcessBuilder callScript( String location ) {
        return new MyProcessBuilder( "something", location );
    }

    public static void main( String[] args ) {
        callScript( "/tmp/bla" ).arg( "something else" ).arg( "more" ).go();
    }
}



回答2:


Write a utility splat() and publish it?:)

This might look more uniform:

List<String> finalArgs = new ArrayList<String>();

finalArgs.addAll(Arrays.asList( "something" ));
finalArgs.addAll(Arrays.asList( scriptLocation ));
finalArgs.addAll(Arrays.asList( extraArgs )));

ProcessBuilder pb = new ProcessBuilder(finalArgs);



回答3:


When you call

ProcessBuilder pb = new ProcessBuilder("something", scriptLocation, /* extraArgs */);

If you have

public ProcessBuilder(String something, String scriptLocation, String... extraArgs);

Then you can call this method in many ways:

ProcessBuilder pb = new ProcessBuilder("something", "/tmp/script.sh");

ProcessBuilder pb = new ProcessBuilder("something", "/tmp/script.sh","someArg");

ProcessBuilder pb = new ProcessBuilder("something", "/tmp/script.sh","someArg","someArg2");



ProcessBuilder pb = new ProcessBuilder("something", "/tmp/script.sh");

ProcessBuilder pb = new ProcessBuilder("something", "/tmp/script.sh",new String[]{});

ProcessBuilder pb = new ProcessBuilder("something", "/tmp/script.sh",new String[]{"someArg"});

ProcessBuilder pb = new ProcessBuilder("something", "/tmp/script.sh",new String[]{"someArg","someArg2"});



ArrayList<String> someStringList = new ArrayList<String>();
someStringList .add("SomeArg");
someStringList .add("SomeArg2");
String[] extraArgs = someStringList .toArray(new String[someStringList .size()]);
ProcessBuilder pb = new ProcessBuilder("something", "/tmp/script.sh",extraArgs);


来源:https://stackoverflow.com/questions/17893026/is-there-an-easier-alternative-to-mimicking-the-splat-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!