HashMap:containsKey()应该是什么时候不是真的?

时间:2012-09-11 13:59:18

标签: java encryption jvm hashmap obfuscation

我目前正在为学校的家庭作业投掷一个混淆程序。我试图让程序读取一个文件然后创建一个新文件,用文件中的每个字母替换一些我从HashMap拉出的相应值。我设置了一大堆键和值,但后来在编写新文件的过程中,我尝试在追加到新String之前检查地图是否包含一个键。检查的字符实际上在我正在读取的文件中进行测试,并且文件被正确读取。然而它失败了encryptionDict.containsKey()(我的hashmap)方法。

我希望有些Java专家可以帮我解决这个问题!我很无能,我更像是一个C和D家伙。令我印象深刻的唯一想法就是使用字符串"foo" != "foo"。但是字符不是对象。

代码位于下面的pastebin中,要查看的关键部分是类构造函数,方法加密和方法initDictionary,也可以有人告诉我为什么HashMap<char, String>无效,是因为我必须使用一个对象?

代码:http://pastebin.com/NcHTHPfw

4 个答案:

答案 0 :(得分:6)

 private HashMap<char [], String> initDictionary() {
                HashMap<char [], String> d = new HashMap<char [], String>();

                d.put("a".toCharArray(), "!\"#¤");
                d.put("b".toCharArray(), "¤#\"!");
                d.put("c".toCharArray(), "\"#¤%");
                d.put("d".toCharArray(), "%¤#\"");
                d.put("e".toCharArray(), "#¤%&");
                d.put("f".toCharArray(), "&%¤#");
                d.put("g".toCharArray(), "¤%&/");
                d.put("h".toCharArray(), "/&%¤");
                d.put("i".toCharArray(), "%&/(");
                d.put("j".toCharArray(), "(/&%");
                d.put("k".toCharArray(), "&/()");
                d.put("l".toCharArray(), ")(/&");
                d.put("m".toCharArray(), "/()=");
                d.put("n".toCharArray(), "=)(/");
                d.put("o".toCharArray(), "()=?");
                d.put("p".toCharArray(), "?=)(");
                d.put("q".toCharArray(), ")=?!");
                d.put("r".toCharArray(), "!?=)");
                d.put("s".toCharArray(), "=?!\"");
                d.put("t".toCharArray(), "\"!?=");
                d.put("u".toCharArray(), "?!\"#");
                d.put("v".toCharArray(), "#\"!?");
                d.put("w".toCharArray(), ";:*^");
                d.put("x".toCharArray(), "^*:;");
                d.put("y".toCharArray(), ":*^>");
                d.put("z".toCharArray(), ">^*:");
// etc.

这是有问题的一点。您不能在Java中使用数组作为散列键,因为Array不会覆盖equals()和hashCode()方法。

hashCode用于查找包含您要查找的对象的正确存储桶,equals()方法用于比较实际的对象。要使用HashMap,您需要以合理的方式覆盖这两个方法,而不能将数组类作为final。因此,如果您绝对坚持使用char数组,那么唯一可以做的就是使用包装类作为具有char数组的键。

这样的事情:

public class Key {
    private final char[] array;

    public Key(final String string) {
        this(string.toCharArray());
    }
    public Key(final char[] array) {
        this.array = array;
    }

    public char[] getArray() {
        return array;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Key key = (Key) o;

        if (!Arrays.equals(array, key.array)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return array != null ? Arrays.hashCode(array) : 0;
    }
}

现在,您可以拥有Map<Key, String>,并可以使用KeyString

中的char[]个对象

答案 1 :(得分:2)

问题是所有char[]都是唯一的,无论其内容如何。看来你真的想要使用String。通常,您可以在不使用char[]

的情况下编写此类程序

相反,你可以写

private Map<Character, String> initDictionary() {
Map<Character, String> d = new HashMap<Character, String>();

d.put('a', "!\"#¤");
// etc

答案 2 :(得分:0)

不要使用数组作为键,它们不具有可比性,因此当它比较时值不匹配

答案 3 :(得分:0)

您正在使用HashMap<char [], String>。这不起作用.equals并且.hashCode未在数组上定义。这个简单的测试程序verifiesthis:

public static void main(String[] args) {
  char[] a = String.valueOf('a').toCharArray();
  char[] b = String.valueOf('a').toCharArray();

  System.out.println(a.hashCode() == b.hashCode());
}

您可以使用Map<Character, String>来达到目的。另一种解决方案是使用由filecontent.charAt(index)索引的数组String [MAX_INDEX] - 如果MAX_INDEX很小(如'z'),这可能更简单。