[Java]HashMap同士を比較する方法

二つのHashMapを比較して、その差異を新しいHashMapに入れたいのですが、方法が分かりません。
教えてください><;

こんな感じです。
なお、key,valueの型はStringに決まっているものとします。

..前略
HashMap<String, String> source = new HashMap<String, String>;
HashMap<String, String> target = new HashMap<String, String>;
HashMap<String, String> difference = new HashMap<String, String>;

source.put("name", "Wee"); //文字列っぽいvalue
source.put("price", "25000"); //intっぽいvalue
source.put("marketShare", "45.51"); //floatっぽいvalue
source.put("eligible", "true"); //booleanっぽいvalue

target.put("name", "ZBOX720");
target.put("price", "27800");
target.put("marketShare", "23.14");
target.put("eligible", "false");

..後略

このsourceとtargetを比較して、次のような結果が欲しいのです。

differenceの中身
"name", "" //文字列同士は比較不能として、比較結果は空文字列
"price", "-2800" //int同士の比較として、25000-27800=-2800
"marketShare", "22.37" //float同士の比較として、45.51-23.14=22.37
"eligible", "false" //trueとfalseの比較結果はfalse、と考える

上記の例では、たかだか四つしか項目がありませんが、実際は数十個あるものと想定してください。
どんなコードを書けばいいのでしょう。。。

回答の条件
  • 1人2回まで
  • 登録:2009/03/31 19:19:48
  • 終了:2009/04/01 14:28:56

回答(1件)

id:bufferings No.1

Mitz回答回数4ベストアンサー獲得回数12009/04/01 01:38:40

ポイント60pt

メソッドでやるなら

  public static void main(String[] args) {
    HashMap<String, String> source = new HashMap<String, String>();
    HashMap<String, String> target = new HashMap<String, String>();
    HashMap<String, String> difference = new HashMap<String, String>();

    source.put("name", "Wee"); // 文字列っぽいvalue
    source.put("price", "25000"); // intっぽいvalue
    source.put("marketShare", "45.51"); // floatっぽいvalue
    source.put("eligible", "true"); // booleanっぽいvalue

    target.put("name", "ZBOX720");
    target.put("price", "27800");
    target.put("marketShare", "23.14");
    target.put("eligible", "false");

    for (Entry<String, String> entry : source.entrySet()) {
      String key = entry.getKey();
      difference.put(key, getDifference(entry.getValue(), target.get(key)));
    }

    System.out.println(difference);
  }

  private static String getDifference(String src, String tgt) {
    String diff = null;
    diff = checkInteger(src, tgt);
    if (diff != null) {
      return diff;
    }
    diff = checkFloat(src, tgt);
    if (diff != null) {
      return diff;
    }
    diff = checkBoolean(src, tgt);
    if (diff != null) {
      return diff;
    }

    return "";
  }

  private static String checkInteger(String src, String tgt) {
    try {
      int src2 = Integer.parseInt(src);
      int tgt2 = Integer.parseInt(tgt);
      return Integer.toString(src2 - tgt2);
    } catch (NumberFormatException e) {
    }
    return null;
  }

  private static String checkFloat(String src, String tgt) {
    try {
      float src2 = Float.parseFloat(src);
      float tgt2 = Float.parseFloat(tgt);
      return Float.toString(src2 - tgt2);
    } catch (NumberFormatException e) {
    }
    return null;
  }

  private static String checkBoolean(String src, String tgt) {
    Boolean src2 = getBoolean(src);
    if (src2 == null) {
      return null;
    }

    Boolean tgt2 = getBoolean(tgt);
    if (tgt2 == null) {
      return null;
    }

    if (src2 && tgt2) {
      return "true";
    } else {
      return "false";
    }
  }

  private static Boolean getBoolean(String str) {
    if (str.equals("true")) {
      return Boolean.TRUE;
    } else if (str.equals("false")) {
      return Boolean.FALSE;
    } else {
      return null;
    }
  }

クラスでやるなら

  public static void main(String[] args) {
    HashMap<String, String> source = new HashMap<String, String>();
    HashMap<String, String> target = new HashMap<String, String>();
    HashMap<String, String> difference = new HashMap<String, String>();

    source.put("name", "Wee"); // 文字列っぽいvalue
    source.put("price", "25000"); // intっぽいvalue
    source.put("marketShare", "45.51"); // floatっぽいvalue
    source.put("eligible", "true"); // booleanっぽいvalue

    target.put("name", "ZBOX720");
    target.put("price", "27800");
    target.put("marketShare", "23.14");
    target.put("eligible", "false");

    for (Entry<String, String> entry : source.entrySet()) {
      String key = entry.getKey();
      difference.put(key, getDifference(entry.getValue(), target.get(key)));
    }

    System.out.println(difference);
  }

  private static Checker[] checkers = new Checker[] { new IntegerChecker(),
      new FloatChecker(), new BooleanChecker() };

  private static String getDifference(String src, String tgt) {
    for (Checker cheker : checkers) {
      String diff = null;
      diff = cheker.check(src, tgt);
      if (diff != null) {
        return diff;
      }
    }
    return "";
  }

  public static interface Checker {
    public String check(String src, String tgt);
  }

  public static class IntegerChecker implements Checker {
    public String check(String src, String tgt) {
      Integer src2 = getInteger(src);
      if (src2 == null) {
        return null;
      }

      Integer tgt2 = getInteger(tgt);
      if (tgt2 == null) {
        return null;
      }

      return Integer.toString(src2 - tgt2);
    }

    private static Integer getInteger(String str) {
      try {
        return Integer.valueOf(str);
      } catch (NumberFormatException e) {
        return null;
      }
    }
  }

  public static class FloatChecker implements Checker {
    public String check(String src, String tgt) {
      Float src2 = getFloat(src);
      if (src2 == null) {
        return null;
      }

      Float tgt2 = getFloat(tgt);
      if (tgt2 == null) {
        return null;
      }

      return Float.toString(src2 - tgt2);
    }

    private Float getFloat(String str) {
      try {
        return Float.valueOf(str);
      } catch (NumberFormatException e) {
        return null;
      }
    }
  }

  public static class BooleanChecker implements Checker {
    public String check(String src, String tgt) {
      Boolean src2 = getBoolean(src);
      if (src2 == null) {
        return null;
      }

      Boolean tgt2 = getBoolean(tgt);
      if (tgt2 == null) {
        return null;
      }

      if (src2 && tgt2) {
        return "true";
      } else {
        return "false";
      }
    }

    private static Boolean getBoolean(String str) {
      if (str.equals("true")) {
        return Boolean.TRUE;
      } else if (str.equals("false")) {
        return Boolean.FALSE;
      } else {
        return null;
      }
    }
  }

ざっくりとですけどね。

丸まるのが嫌だったらBigDecimalとか使うのかな。

id:arukichigai

ありがとうございます!

助かりました!

2009/04/01 14:28:44
  • id:tdoi
    高々数十個の項目とのことですが、これは固定でしょうか?
    つまり、数十個は決めてしまえば、それ以降は追加や変更がなく、例えば、nameは文字列、intは整数と判断してよいかどうかということです。

    また、扱うデータ種別は固定でよいですか?例えば、int、float、文字列、真偽値の4つと思ってよいですか?


    この前提の両方とも問題があるようであれば、ちょっとどこか妥協する必要があるかもしれません。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません