0

これが私のソースコードです。ユーザーに質問をし、その答えが「はい」または「いいえ」であると期待し、ユーザーが「はい」または「いいえ」の質問に答えた場合にのみ終了する単純なプログラムを実装しようとしています。私が提案した本は、==比較を使用せず、代わりにequalsメソッドを使用して、ユーザーが「yes」ではなく「yes」と入力したかどうかをプログラムが理解できるようにすることを提案しました。しかし、このように結果は同じであり、メソッドは、それが正確に「はい」または「いいえ」である場合、ユーザーの回答を比較しているように見えます。たとえば、「no」の回答は受け付けません。それはその方法にとって論理的ですか?それはそのように機能することになっていますか?「はい」「はい」「いいえ」「いいえ」などの回答を受け入れるようにプログラムを変更するにはどうすればよいですか。?私はあなたの助けをいただければ幸いです:)

import acm.program.*;

public class YesNoExample extends ConsoleProgram{
public void run(){
    while(true){
    String answer = readLine("Would you like instructions? ");
    if(askYesNoQuestion(answer)){
        break;
    }
    println("Please answer yes or no.");
    }
}

private boolean askYesNoQuestion(String str){
    if(str.equals("yes")||str.equals("no")){
        return true;
    }else{
        return false;
    }
}

}
4

4 に答える 4

2

使用する場合は、2つのStringオブジェクトの参照(メモリポインタ)を==比較します。を使用すると、クラス内のカスタムメイドのメソッドが実行され、「インテリジェント」な比較が行われます。この場合、文字がすべて同じであり、全体の長さが同じであることを確認してください。equalsString

大文字と小文字の混合をサポートしたい場合は、を使用できます"someString".equalsIgnoreCase("SoMeString")(trueを返します)。これは(大まかに言って)両方の文字列を小文字にし(大文字と小文字は関係ありません)、equalsを使用してそれらを比較することによって行われます。

編集:他のポスターは、大文字と小文字の区別に加えて、スペースが重要ではない文字列の同等性も探したいと私に気づかせました。その場合は、すべてを小文字に変換するのと同様のトリックが適用されます。ここでは、@ LouisWassermanが回答で述べているように、最初にすべてのスペースを削除します。

于 2012-07-05T16:14:32.150 に答える
1

はい/いいえをあいまいに識別する必要がある場合は、最初に、何が一致するかについて正確なルールが必要です。あなたの例に基づいて、私はこれを提案することができます:

private boolean askYesNoQuestion(String str) {
  str = str.replace(" ", "").toUpperCase();
  return str.equals("YES") || str.equals("NO");
}

最高のパフォーマンスに興味があり、了解度にはまったく興味がない場合は、次を使用してください。

private static final Pattern p = 
    Pattern.compile("y\\s*e\\s*s|n\\s*o", Pattern.CASE_INSENSITIVE);
private boolean askYesNoQuestion(String str) {
  return p != null && p.matcher(str.trim()).matches();
}
于 2012-07-05T16:48:25.687 に答える
0

==vsのセマンティクス.equals()

まず、セマンティクスを誤解します。

==オブジェクトの同一性をテストします。A == BAまったく同じオブジェクトへの参照Bです。

.equals()カスタムロジックを適用して、オブジェクトがまったく同じオブジェクトでなくても、何らかの論理的な方法で等しいかどうかをテストします。これを正しく実装するには、両方のオブジェクトも同じ.hashCode()値である必要があります。

慣用的なJavaソリューション

Stringオブジェクトはであるため、final継承することはできません。.equals()オブジェクトのをオーバーライドすることはできませんString

あなたがする必要があるのは、入力を前処理して、ターゲット値と直接比較できるものにすること.equalsIgnoreCase()です。

これを行う1つの方法は、を使用answer.replaceAll("\\s","")してすべての空白を削除し、それをターゲットStringリテラルと比較すること.equalsIgnoreCase()です。

置き換えるためのより良い方法askYesNoQuestion()は次のとおりです。

private boolean isAnswerYesOrNo(final String answer)
{
    final String input = answer.replaceAll("\\s","");
    return "yes".equalsIgnoreCase(input) || "no".equalsIgnoreCase(input);
}

literalaを入力パラメーターと比較すると、NullPointerExceptions入力パラメーターがたまたまnull「yes」であるかどうかがわかります。equalsIgnoreCase()can never throw aNullPointerException`。これは慣用的なJavaです。

より良い本を手に入れよう

その本は、あなたが主張していることを本当に言っているのであれば、あまり役に立ちません。また、それが完全なアンチパターンであり、適切に設計されたプログラムが、入力を修正するために何ができるかという正確な問題の詳細な説明で終了する場合、不正な入力を処理するための多くのコードを書くことを教えています。

于 2012-07-05T16:13:25.160 に答える
-1

上記で説明した==と.equalsの説明とともに、必要な比較を行う1つのライナーの2つの例を次に示します。

if ( Pattern.matches("\\s*[yY]\\s*[eE]\\s*[sS]\\s*", input) ) {
  // do something
}


if ( input.replaceAll("\\s", "").equalsIgnoreCase("yes") ) {
  // do something
}
于 2012-07-05T16:58:49.987 に答える