タグ別アーカイブ: Android

Java .equalsメソッドの罠

Javaの.equalsメソッドの罠にひっかかって2週間くらいなやんだのでメモります。
開発してるTwitMorseの逆変換機能の実装の時に直面しました。

equalsメソッドは時折同じ文字列の比較をしてもfalseを返すことがあります。

私が引っかかったコード

protected String convertMorseToText(String text) { 
     String[] morse = text.split(" ", 0);
     for (String moji : morse) { 
     if (moji.equals("--・--")) { 
         convertText += moji.replaceAll("--・--", "ア"); 
     } 
     return convertText; 
}

何をしたかったかというと、
textで入ってきたモールス信号を全角空白で分割し、”ーー・ーー”という文字列があった場合に「ア」に変換して返す
というものでした。

if (moji.equals("--・--")) {

しかし、この一文はfalseとなりスルーされてしまいます。何度”ーー・ーー”を入力しても一致しないものとして処理されていました。
これに2、3週間悩みました。

デバッガで調べていたところどこでfalseになっていたかというと、
Stringクラスのequalsメソッドのある部分でfalseが返されていました。

    @Override public boolean equals(Object other) {
        if (other == this) {
          return true;
        }
        if (other instanceof String) {
            String s = (String)other;
            int count = this.count;
            if (s.count != count) {
                return false;
            }
            // TODO: we want to avoid many boundchecks in the loop below
            // for long Strings until we have array equality intrinsic.
            // Bad benchmarks just push .equals without first getting a
            // hashCode hit (unlike real world use in a Hashtable). Filter
            // out these long strings here. When we get the array equality
            // intrinsic then remove this use of hashCode.
            if (hashCode() != s.hashCode()) {// ここにひっかかる
                return false;
            }

どうもhashCodeの違いでequalsを使っても一致しなかったらしい。

そこで以下のように書き換えてみたところうまく機能した。

protected String convertMorseToText(String text) { 
     String[] morse = text.split(" ", 0);
     for (String moji : morse) { 
     String enc = new String(moji);
     if (enc.equals("--・--")) { 
         convertText += enc.replaceAll("--・--", "ア"); 
     } 
     return convertText; 
}

入力されたtextを全角空白で分割する所までは一緒。
違いは、新しくencという文字列をmojiを使って生成して比較するという部分でした。
これでhashCodeの違いを解消できました。

equalsメソッドをオーバーライドしたりhashCodeメソッドをオーバーライドしたりという解決方法もあるにはあったのですが、自分はこの方法でequalsメソッドの罠を回避しました。

後学のためにメモとして残しておきます。

R.array.listの書き方と用途メモ

以下のようなコードでR.array.listを見かけて作り方がわからなかったのでも私的メモを残す
[java]
// ListViewにデータをセットする
ArrayAdapter<charsequence> adapter = ArrayAdapter.createFromResource(self, R.array.list, android.R.layout.simple_list_item_1);
[/java]
続きを読む R.array.listの書き方と用途メモ

ADT(eclipse)日本語化手順(Windows版)

ADT(Android Development Tools)に入っているeclipseを日本語化する手順メモします。
英語でも余裕、今すぐ開発したいという方は必要ありませんがなんだかんだで日本語化しておいたほうが効率が上がるような気がしたので、入れることにしました。。

WindowsでのAndroidアプリ開発環境の導入(ADTの導入)手順についてはAndroidアプリ開発環境 構築手順(Windows版)に書きました。
続きを読む ADT(eclipse)日本語化手順(Windows版)

自作Androidアプリ アップデート版リリースメモ

自作Androidアプリのアップデート手順をまとめる。
既に自作のアプリをplaystoreに公開している前提で記す。
続きを読む 自作Androidアプリ アップデート版リリースメモ

久々にAndroid―オリジナル時計アプリー!

ここのところ研究室で開催している講習会に追われてまともにモバイルアプリを書いてなかったので、なんか作ろうとおもってました。
そんなとき、部屋のデジタル時計が壊れていることに気づきました。ついこの前時間調整をしたのにいつの間にか2000年の1月1日にタイムスリップしていました。恐らくどこかの時間保存用の集積回路が壊れたのでしょう。それもそのはず、これまで何度も布団から落っことしてましたから。そんなわけで時計アプリでも作るかーと思いたち、さくっと作ってみました。

続きを読む 久々にAndroid―オリジナル時計アプリー!

俺の愛機はIS01

まあメイン端末はiPhone4Sになっちゃうけどね。IS01はかわいいよ・・・本当に。一生懸命デバッグ用端末としてメモリをフルに使って動いてくれてるところとか・・・ほんとかわいい。。。
続きを読む 俺の愛機はIS01