2012-09-11 17 views
5

Actualmente estoy lanzando un programa de ofuscación para la tarea escolar. Estoy intentando hacer que el programa lea un archivo y luego crear un nuevo archivo que reemplace cada letra en el archivo con algún valor correspondiente que saque de HashMap. Configuré un montón de claves y valores, pero más adelante en el proceso de escribir el nuevo archivo trato de verificar si el mapa contiene una clave antes de agregar al nuevo String. Los caracteres que están marcados están, de hecho, en el archivo que estoy leyendo para probar y el archivo se lee correctamente. Sin embargo, falla con el método encryptionDict.containsKey() (mi hashmap).HashMap: containsKey() ¿No es verdadero cuando debería ser?

¡Espero que algún experto en Java me ayude a resolver esto! No tengo ni idea, soy más un tipo C y D. El único pensamiento que me llamó la atención fue que sería algo así como con Strings donde "foo" != "foo". Pero los caracteres no son objetos.

El código está en un Pastebin continuación, las piezas clave a tener en cuenta es el constructor de la clase, el cifrar método, y el método initDictionary, también puede alguien decirme por qué HashMap<char, String> no es válido, es porque tengo que usar una ¿objeto?

El código: http://pastebin.com/NcHTHPfw

+0

¿Usó un depurador para ver para qué valores está fallando? – Tudor

+0

Sí, parece que los personajes me permiten omitir el todo para la conversión de CharArray() – BitPuffin

+0

¡Eh, no, no lo hice!Realmente no sé cómo usar el depurador. Sólo cómo configurar un punto de interrupción, etc. Pero podría intentar – BitPuffin

Respuesta

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. 

Este es el poco problemático. No puede usar matrices como claves hash en Java, ya que Array no anula los métodos equals() y hashCode().

El hashCode se utiliza para encontrar el cubo correcto que contiene el objeto que está buscando, y el método equals() compara los objetos reales. Para hacer uso de un HashMap, debe anular ambos métodos de una manera sensata, lo cual no es posible ya que las clases de arreglos son finales. Entonces, lo único que podría hacer si insiste completamente en usar matrices de caracteres es usar una clase contenedora como clave que tiene una matriz de caracteres.

Algo como esto:

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

Ahora usted puede tener un Map<Key, String> y Bould un objeto Key ya sea de un String o una char[]

+2

'String' es una buena clase de contenedor para una matriz de caracteres :-) –

+0

Bueno, yo quería usar char de alguna manera porque es fácil llamar a charAt en una cadena, es un Es una pena que no haya una carta en el método o algo así. – BitPuffin

+0

@FrankPavageau cierto, pero a veces por razones de seguridad, no es legal usar String en métodos confidenciales debido a la agrupación de cadenas, etc. –

2

El problema es que todos char[] es único, independientemente de su contenido . Parece que realmente quieres usar un String. Normalmente, se puede escribir un programa de este tipo sin necesidad de utilizar un char[]

su lugar se puede escribir

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

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

O tal vez 'Character', ya que parece que todas las claves son en realidad caracteres únicos. –

0

No utilice matrices como la clave, no son comparables, por lo que cuando se compara el valor no coincide con

0

Está utilizando un HashMap<char [], String>. Esto no funciona ya que .equals y .hashCode no están definidos en las matrices. Este programa de prueba simple 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()); 
} 

Se puede usar un Map<Character, String> para sus propósitos. Otra solución sería usar una cadena de matriz [MAX_INDEX] que está indexada por filecontent.charAt(index); esto puede ser incluso más simple si MAX_INDEX es pequeño (como 'z') en su caso.

Cuestiones relacionadas