Parametri stringa Java


Vengo da uno sfondo.net e voglio conoscere il modo accettato di creare un metodo che restituisce un booleano e modifica una stringa che è stata passata tramite il parametro. Capisco che le stringhe siano immutabili in Java, quindi lo snippet sottostante produrrà sempre una stringa vuota. Sono costretto a restituire solo booleano. Le eccezioni non possono essere generate. Se ho bisogno di avvolgere la classe String in, ad esempio, un StringHolder, in quale pacchetto potrei trovarlo.

public static void DoStuff()
{
    String msg = "";
    if (GetMessage(msg))
    {
       System.out.println(msg);
    }
}
Author: tgeros, 2008-12-05

11 answers

Usa un java.lang.StringBuilder-fondamentalmente una stringa mutabile. Tuttavia, sarebbe più sicuro e più "stile Java" restituire la stringa modificata.

 9
Author: Michael Borgwardt, 2008-12-05 01:28:07

Ti consiglio vivamente di non usare StringBuilder, holder o simili. Sono hack. Vuoi lavorare con le stringhe, non con i costruttori.

L'approccio più ovvio è quello di restituire un oggetto contenente i dati che si desidera restituire. Di David [bombe.livejournal.com la soluzione] copre questo, quindi non lo ripeterò. Tuttavia, suggerirei invece di cercare di renderlo generico palla di dati, renderlo specifico. Rendilo come un oggetto, forse potrebbe persino far crescere un comportamento reale. (E se voglio davvero andare in città, nascondere il costruttore e dargli invece un metodo di creazione statico.)

Un secondo approccio, non così ben supportato in Java, è quello di invertire le chiamate. Invece di restituire un risultato, dire a un callback il risultato.

Il codice di utilizzo (più importante) sarebbe qualcosa di simile (sembra un po ' strano perché non è specifico, né generico):

String userMessage = thing.doStuff(new StuffHandler<String>() {
    public String stuff(boolean success, String message) {
        return message+" was "+(success ? "succesful" : "unsuccesful");
    }
});

L'implementazione è simile a:

public interface StuffHandler<T> {
    T stuff(boolean success, String message);
}

[...]

    public <T> T doStuff(StuffHandler<T> handler) {
        handler.stuff(isSuccess(), getMessage());
    }

Un terzo approccio è semplicemente quello di rompere il metodo in due. Che può o non può essere fattibile.

 6
Author: Tom Hawtin - tackline, 2015-05-07 12:59:36

Prima di tutto probabilmente non avrei questi requisiti. Sono sicuro che possono essere risolti. Se non vuoi farlo, ti consiglio di restituire un oggetto contenitore per i tuoi due risultati:

public class ResultContainer {
    private final boolean success;
    private final String result;
    public ResultContainer(boolean success, String result) {
        this.success = success;
        this.result = result;
    }
    public boolean isSuccess() { return success; }
    public String getResult() { return result; }
}

E nel tuo codice principale:

ResultContainer resultContainer = GetMessage(message);
if (resultContainer.isSuccess()) {
    System.out.println(resultContainer.getResult());
}

GetMessage() ovviamente creerebbe una nuova istanza di ResultContainer e la restituirebbe, riempita con i valori restituiti.

(L'uso di generici per il ResultContainer è lasciato come esercizio per il lettore.)

 5
Author: Bombe, 2008-12-05 11:37:35

Una classe di supporto più elegante potrebbe essere riutilizzata per qualsiasi tipo di oggetto utilizzando generici:

public class Holder<T> {
  T item;
  public Holder( T item) { set( item);}
  public T get( ) { return item;}
  public void set( T item) { this.item = item;}
}

DoStuff( ) sarebbe quindi simile a:

public static void DoStuff( ) {
  String msg = "";
  Holder<String> holder = new Holder<String>( msg);
  if ( getMessage( holder)) { System.out.println( holder.get( ));}
}

E GetMessage( ) dovrebbero chiamare holder.set( a_string).

 3
Author: J. A. Faucett, 2008-12-05 04:55:50

Java è un linguaggio orientato agli oggetti basato su classi, quindi i suoi idiomi tendono a creare classi per incapsulare i dati con il comportamento che lo circonda.

Hai un dato - il messaggio - che si ottiene in qualche modo, quindi se viene soddisfatta qualche condizione, viene fatto qualcos'altro con esso. Rendere quel comportamento una sequenza di gets, ifs e altre operazioni in un oggetto di controllo esterno è spesso un segno che il programmatore non ha capito OOP.

Sono costretto a restituire solo booleano. Le eccezioni non possono essere generate.

Posso suggerire che dovresti usare Fortran o C piuttosto che Java? I linguaggi procedurali hanno spesso l'idioma della mutazione e il ritorno di un flag, che si adatta bene a quel paradigma (in assenza di gestione automatica della memoria, il chiamante crea e passa in un buffer che viene popolato; questo consente al buffer di essere liberato in modo sicuro quando il chiamante è fatto con esso; Java non ha bisogno di farlo, quindi se si guardaget () restituisce un Stringa o null se fallisce - non è necessario gestire la memoria nel chiamante). Almeno, non preoccuparti di cercare di trovare il modo accettato di farlo in Java idiomatico - con quei vincoli, non lo sarà, e chiunque li stia forzando su di te ha fatto una cattiva scelta, il che significa che hai degli hack o finisci con un codice dettagliato cercando di fare una soluzione non hacky.

 2
Author: Pete Kirkham, 2008-12-05 13:56:31

Non è possibile utilizzare una stringa come parametro di output. Il modo per farlo sarebbe usare invece una classe StringBuilder o restituire null per un errore.

Discussione qui

 1
Author: JamesSugrue, 2008-12-05 01:28:44

Le stringhe sono immutabili, quindi sì, sarà necessario avvolgere la stringa in un StringHolder. Puoi scrivere il tuo semplicemente come

  class StringHolder
  {
     String msg;
  }

  StringHolder sMsg = new StringHolder();
  sMsg.msg = "";
  if (GetMessage(sMsg))
  {
     System.out.println(sMsg.msg);
  }
 1
Author: Paul Tomblin, 2008-12-05 01:29:38

Un StringHolder banale sarebbe una stringa[1].


bool GetMessage(String[] output)
{
     if(output.length < 1)
          throw new Exception("Output must be a String[1]");
     output[0] = "You win!";
}

public static void DoStuff()
{
      String[] msg = new String[1];
      if(GetMessage(msg))
      {
          System.out.println(msg[0]);
      }
}

StringBuilder è probabilmente il modo canonico per farlo, però.

 1
Author: Stobor, 2008-12-05 02:20:11

Questo è uno strano requisito.

Perché non farlo nel modo giusto (o almeno nel modo java ) ? È come cercare di ottenere due risultati da una funzione. Come sottrarre (2 , 2 ) restituisce 0 e "Buongiorno signore".

Beh, comunque, puoi provare queste due opzioni.

1st. StringBuilder Non è la cosa migliore da usare, dal momento che non stai "costruendo" una stringa.

public static void doStuff(){
    String msg = "";
    StringBuilder sb = new StringBuilder();
    if ( getMessage( sb ) ) {
        System.out.println( sb );
    }
}

public static boolean getMessage( StringBuilder sb ) {
    if ( "".equals( sb.toString() )) {
        sb.delete( 0, sb.length() );
        sb.append("It was empty");
        return true;
    } else {
        return false;
    }
}

2nd StringHolder (qualsiasi supporto per quella materia) Non troppo stile java, ma fai il lavoro. Questo sarebbe quello usato dalla maggior parte degli sviluppatori java che conosco.

public static void doStuff(){
    String msg = "";
    String [] holder = { msg };
    if ( getMessage( holder ) ){
        System.out.println( holder[0]  );
    }
}
public static boolean getMessage( String [] holder ) {
    if ( "".equals(  holder[0] )) {
        holder[0] = "It was empty";
        return true;
    } else {
        return false;
    }
}

3°. Opzione. non quello che hai chiesto, ma quello che avrei fatto. Sfortunatamente viola la condizione "return boolean".

public void doStuff() { 
    String msg = "";
    String result = getMessage( msg );
    if ( result != msg ) {
        System.out.println( result );
    }
}
public static String getMessage( String msg ) {
    if ( "".equals(msg){
        return "It was empty";
    }
    return msg
}

Scegli uno.

Nota

Anche se non a tutti piace questo ( Jon Skeet direbbe "Non è universalmente accettato" ) , per favore dai un'occhiata allo stile di codifica java che sto usando ( metodi che iniziano con minuscole e parentesi graffe nella stessa riga ). A volte lo è importante rispettare la piattaforma in cui stai codificando. Almeno questo è quello che faccio quando codice in c# (molto raramente btw )

 1
Author: OscarRyz, 2008-12-05 03:06:39

public boolean doStuff(String msg) { boolean boolTest = false; msg += "Appending something to msg"; int msgLength = msg.length(); if ( msgLength > 80 ) { boolTest = true; return boolTest; } return boolTest; }

È questo tipo di quello che stai cercando? Presumo che il test booleano sia qualcosa come testare se il messaggio modificato è troppo lungo per un display (maggiore di 80 lunghezza) o qualcosa di simile, e che non è necessario chiamare un altro metodo per cambiare la stringa del messaggio all'interno di doStuff().

Potrebbe essere completamente fuori base qui, però. :-)

 0
Author: , 2008-12-20 01:43:22

Prima scrivi i programmi e li fai dal codice in questo modo:

Process p = Runtime.exec("java GetMessage.class " + String);

Suggerimento per te: Runtime.exec dovrebbe essere usato ovunque. Quindi puoi creare molti programmi.

Quindi aspetta di recuperare un codice di stato come questo:

if (p.returnCode() = 1) 
  Out.printWord("1 made back"):
else 
  {
  Out.printWord("B Made back");
  }

In questo modo puoi usare il programma altrimenti come lato esterno di questo programma. È bene rendere il codice resusable. Credimi, ci sono dentro da anni. Questo è il modo in cui i professionisti fanno codice.

 0
Author: , 2008-12-20 02:18:28