2

私は.netのバックグラウンドから来ており、ブール値を返し、パラメーターを介して渡された文字列を変更するメソッドを作成する受け入れられた方法を知りたいです。Java では文字列が不変であることを理解しているため、以下のスニペットでは常に空の文字列が生成されます。ブール値のみを返すように制約されています。例外はスローできません。String クラスを、たとえば StringHolder でラップする必要がある場合、どのパッケージでこれを見つけることができますか?

public static void DoStuff()
{
    String msg = "";
    if (GetMessage(msg))
    {
       System.out.println(msg);
    }
}
4

11 に答える 11

9

java.lang.StringBuilder を使用します - 基本的に可変文字列です。ただし、変更された文字列を返す方がより安全で、より「Java スタイル」になります。

于 2008-12-05T01:28:07.143 に答える
6

StringBuilder、ホルダーなどを使用しないことを強くお勧めします。彼らはハックです。ビルダーではなく、文字列を操作したい。

最も明白なアプローチは、返したいデータを含むオブジェクトを返すことです。David の [bombe.livejournal.com の] ソリューションはそれをカバーしているので、繰り返しません。ただし、データの一般的なボールを作ろうとする代わりに、具体的にすることをお勧めします。オブジェクトのようにしてください。おそらく、実際の動作を成長させることさえできます。(そして、本当に町に行きたい場合は、コンストラクターを非表示にして、代わりに静的な作成メソッドを指定してください。)

Java ではあまりサポートされていない 2 番目の方法は、呼び出しを逆にすることです。結果を返す代わりに、コールバックに結果を伝えます。

(より重要な) 使用法コードは次のようになります (特定のものでも一般的なものでもないため、少し奇妙に見えます):

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

実装は次のようになります。

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

[...]

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

3 つ目のアプローチは、単純にメソッドを 2 つに分割することです。それは実現可能かもしれないし、不可能かもしれません。

于 2008-12-05T12:18:07.907 に答える
5

まず最初に、私はおそらくこれらの要件を持っていないでしょう。彼らは回避できると確信しています。それを望まない場合は、2つの結果のコンテナオブジェクトを返すことをお勧めします。

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; }
}

そしてあなたのメインコードで:

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

GetMessage()明らかにaの新しいインスタンスを作成し、ResultContainerそれを返し、戻り値で埋めます。

(ジェネリックスの使用ResultContainerは、読者の演習として残されています。)

于 2008-12-05T11:37:35.697 に答える
3

より洗練されたホルダー クラスは、ジェネリックを利用することで、あらゆるタイプのオブジェクトに再利用できます。

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( )次に、次のようになります。

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

GetMessage( )呼び出す必要がありますholder.set( a_string)

于 2008-12-05T04:55:50.267 に答える
2

Javaはクラスベースのオブジェクト指向言語であるため、そのイディオムは、データを取り巻く動作でデータをカプセル化するクラスを作成する傾向があります。

何らかの方法で取得されたデータ(メッセージ)があり、何らかの条件が満たされた場合は、それを使用して別の処理が行われます。その動作を外部制御オブジェクトでのgets、ifs、およびその他の操作のシーケンスにすることは、多くの場合、プログラマーがOOPを理解していないことを示しています。

私はブール値のみを返すように制約されています。例外をスローすることはできません。

JavaではなくFortranまたはCを使用することをお勧めしますか?手続き型言語には、多くの場合、ミューテーションとフラグを返すというイディオムがあります。これは、そのパラダイムに適しています(自動メモリ管理がない場合、呼び出し元は、入力されたバッファーを作成して渡します。これにより、バッファーを安全に解放できます。呼び出し元はそれで完了です。Javaはそれを行う必要がないため、Map.get()を見ると、失敗した場合は文字列またはnullを返します。呼び出し元のメモリを管理する必要はありません)。少なくとも、慣用的なJavaでそれを行うための受け入れられた方法をわざわざ見つけようとしないでください-それらの制約があると、そうはなりません、そしてあなたにそれらを強制している人は誰でも悪い選択をしました、それはあなたがハックを持っていることを意味します、または、ハッキーでないソリューションを作成しようとする冗長なコードになってしまいます。

于 2008-12-05T12:43:27.637 に答える
1

文字列を出力パラメーターとして使用することはできません。これを行う方法は、代わりに StringBuilder クラスを使用するか、失敗した場合に null を返すことです。

議論はこちら

于 2008-12-05T01:28:44.287 に答える
1

文字列は不変であるため、文字列を StringHolder でラップする必要があります。次のように簡単に自分で書くことができます

  class StringHolder
  {
     String msg;
  }

  StringHolder sMsg = new StringHolder();
  sMsg.msg = "";
  if (GetMessage(sMsg))
  {
     System.out.println(sMsg.msg);
  }
于 2008-12-05T01:29:38.577 に答える
1

単純な StringHolder は String[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 はおそらく標準的な方法です。

于 2008-12-05T02:20:11.267 に答える
1

それはいくつかの奇妙な要件です。

なぜそれを正しい方法 (または少なくとも Java の方法) で行わないのですか? 関数から 2 つの結果を取得しようとするようなものです。Subtract( 2 , 2 ) と同様に、0 と「おはようございます」を返します。

とにかく、これらの 2 つのオプションを試すことができます。

1位。StringBuilder String を「構築」していないため、使用するのに最適なものではありません。

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;
    }
}

2番目のStringHolder(そのことについては何でもホルダー) Javaスタイルでもありませんが、仕事をします。これは、私が知っているほとんどの Java 開発者が使用するものです。

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番目。オプション。あなたが何を求めたかではなく、私が何をするか。残念ながら、「ブール値を返す」条件に違反しています。

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
}

1 つ選択します。

ノート

誰もがこれを好むわけではありませんが (Jon Skeet は「広く受け入れられていません」と言うでしょう)、私が使用している Java コーディング スタイル (小文字で始まり、同じ行に中括弧で始まるメソッド) を見てください。コーディングしているプラ​​ットフォームを尊重することが重要な場合があります。少なくとも、C# でコーディングするときはそうしています (非常にまれです)。

于 2008-12-05T03:00:07.863 に答える
0

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; }

これはあなたが探しているものですか?ブール値のテストは、変更されたメッセージが表示するには長すぎるかどうか (80 を超える長さ) などをテストするようなものであり、doStuff 内のメッセージ文字列を変更するために別のメソッドを呼び出す必要はないと想定しています。 ().

ただし、ここでは完全に基地外になる可能性があります。:-)

于 2008-12-20T01:43:22.513 に答える
0

最初にプログラムを書き、次のようなコードから作成します。

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

ヒント: Runtime.exec はどこでも使用する必要があります。そうすれば、たくさんのプログラムを作ることができます。

次に、次のようなステータス コードが返されるのを待ちます。

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

このようにして、このプログラムの外側のようにプログラムを使用できます。コードを再利用可能にすることは良いことです。私からそれを取ってください、私は何年もそこにいます。これが、プロがコードを作成する方法です。

于 2008-12-20T02:18:28.420 に答える