2012-09-11 10 views
5

Obecnie pracuję wspólnie nad programem obfuskacji do zadań domowych w szkole. Próbuję uczynić program odczytać plik, a następnie utworzyć nowy plik, który zamienia każdą literę w pliku z pewną odpowiednią wartością, którą pobieram od HashMap. Przygotowałem całą masę kluczy i wartości, ale później w trakcie pisania nowego pliku próbuję sprawdzić, czy mapa zawiera klucz przed dodaniem do nowego String. Sprawdzane znaki znajdują się w pliku, który odczytuję, aby przetestować, a plik zostanie odczytany poprawnie. A jednak nie działa z metodą encryptionDict.containsKey() (moja niemasza).HashMap: containsKey() Nieprawdziwe, kiedy powinno być?

Mam nadzieję, że jakiś ekspert od Javy pomoże mi to obliczyć! Jestem całkiem nieświadomy, jestem bardziej z C i D. Jedyna myśl, która mnie uderzyła, polegała na tym, że było to coś w rodzaju Strings, gdzie "foo" != "foo". Ale znaki nie są obiektami.

Kod znajduje się poniżej w wątku, kluczowymi częściami do obejrzenia jest konstruktor klasy, metoda szyfrowania i metoda initDictionary, czy ktoś może mi powiedzieć, dlaczego HashMap<char, String> jest nieważny, czy to dlatego, że muszę użyć obiekt?

Kod: http://pastebin.com/NcHTHPfw

+0

Czy korzystasz z debuggera, aby sprawdzić, które wartości są wadliwe? – Tudor

+0

Tak, wygląda na to, że Postacie pozwolą mi przejść do konwersjiCharArray() – BitPuffin

+0

Eh, nie, nie!Naprawdę nie wiem, jak korzystać z debuggera. Jak ustawić breakpoint itp. Ale mógłbym spróbować – BitPuffin

Odpowiedz

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. 

Jest to problematyczne bit. Nie możesz używać tablic jako kluczy mieszających w Javie, ponieważ Array nie zastępuje metod equals() i hashCode().

Kod mieszający służy do znalezienia właściwego zasobnika zawierającego obiekt, którego szukasz, a metoda equals() porównuje rzeczywiste obiekty. Aby skorzystać z HashMap, musisz nadpisać obie te metody w rozsądny sposób, czego nie możesz, ponieważ klasy tablicy są ostateczne. Więc jedyną rzeczą, którą możesz zrobić, jeśli absolutnie nalegasz na używanie tablic znaków, jest użycie klasy opakowania jako klucza z tablicą znaków.

coś takiego:

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

Teraz można mieć Map<Key, String> i Bould się Key obiekt z albo String lub char[]

+2

'String' jest ładną klasą wrappera dla tablicy char :-) –

+0

No cóż, chciałem jakoś użyć char, ponieważ łatwo jest wywołać charAt na Stringie, jest to szkoda, że ​​nie ma metody letterAt lub czegoś takiego! – BitPuffin

+0

@FrankPavageau prawda, ale czasami ze względów bezpieczeństwa nie jest dozwolone używanie String w metodach poufnych ze względu na łączenie ciągów itp. –

2

Problem polega na tym, że wszystkie char[] są wyjątkowe, niezależnie od ich treści . Wygląda na to, że naprawdę chcesz używać Stringa. Normalnie, można napisać taki program bez użycia char[]

Zamiast tego można napisać

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

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

A może 'Character', ponieważ wydaje się, że wszystkie klucze są w rzeczywistości pojedynczymi postaciami. –

0

Nie używać tablic jako klucz, nie są one porównywalne, więc kiedy porównuje wartość nie pasuje

0

Używasz . To nie działa tak, jak .equals i .hashCode nie są zdefiniowane na tablicach. Ten prosty program testowy 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()); 
} 

Można użyć Map<Character, String> do swoich celów. Innym rozwiązaniem byłoby użycie tablicy String [MAX_INDEX], która jest indeksowana przez filecontent.charAt(index) - może to być jeszcze prostsze, jeśli MAX_INDEX jest mały (jak "z") w twoim przypadku.

Powiązane problemy