2010-02-28 6 views
0

Je dois comparer deux tables et dire à l'utilisateur quelle est la différence entre deux tables.Comparer deux tables en Java

Tableau 1

------+--------- 
|Code | Label | 
------+--------- 
|a1 | a1text | 
------+--------- 
|b1 | b1text | 
------+--------- 
|c1 | bartext1| 
------+--------- 
|e1 | foo  | 
-----+--------- 

Tableau 2

------+--------- 
|Code | Label | 
------+--------- 
|a1 | a1text | 
------+--------- 
|b1 | b2text | 
------+--------- 
|d1 | bartext2| 
------+--------- 
|f1 | bar  | 
------+--------- 

Comparaison Infos
Comme vous le voyez dans le tableau 1 pour l'étiquette code c1 est bartext1 et étiquette code d1 est bartext2. Ils sont même attendent le dernier caractère. Je dois mettre dans mon rapport ils sont mêmes sauf le dernier caractère. Il y a peu de lignes dans les tableaux où il peut y avoir un mot ou un caractère spécial et sa position est n'importe où. D'une manière ou d'une autre, je dois dire dans le rapport que les deux étiquettes sont les mêmes, que le mot manque ou qu'il y a un caractère spécial dans l'un d'entre eux. Le code n'est pas important dans le rapport.

Plus d'info
Ces données provient de troisième party.Code est toujours unique, ils ne sont pas des codes en double. Il est possible que deux codes aient une valeur similaire

Code | Étiquette

ER4 | j'ai un frère

WE3 | J'ai un frère

sortie attendue doit être

  1. Les étiquettes sont différentes dans les deux tableaux. L'étiquette Table1 est: b1text et l'étiquette Tabl2 est: b2text.
  2. Les étiquettes sont différentes dans deux tables. L'étiquette Table1 est: bartext1 et l'étiquette Tabl2 est: bartext2. L'étiquette foo est manquante dans le tableau 2.
  3. barre d'étiquette est manquante dans le tableau 1.
+0

Attendez-vous de nous un code source complet avec des tests unitaires et un script d'installation? – Roman

+0

Les tables sont-elles déjà triées? Les codes en double sont-ils autorisés? Êtes-vous autorisé à utiliser des routines de bibliothèque telles que Google Collections, Jakarta Common Collections ou est ce devoir? – Fortyrunner

+0

Les tables sont-elles déjà triées? NON Les codes en double sont-ils autorisés? NO utilise des routines de bibliothèque telles que Google Collections, Jakarta Common Collections?OUI est ce devoir? NON – NETQuestion

Répondre

2

Je créerais une abstraction pour cet objet Table avec une implémentation égale qui cacherait tous les détails des clients. Java est un langage orienté objet, il est donc préférable d'utiliser les objets pour leur raison d'être.

+0

@duffymo Fine en général, mais 'equals()' est censé donner 'true' ou' false' en sortie, pas celui décrit ci-dessus. Donc, pour cette tâche spécifique, il faudrait implémenter un algorithme de comparaison différent de toute façon. –

+0

Donc, si vous avez besoin de retourner une liste des codes de raison, écrivez une autre méthode. Le point "penser en termes d'objets" reste valable. – duffymo

1

Il y a un framework Open Source Java qui fait cela:

www.diffkit.org

1

Cela a fonctionné pour moi, s'il vous plaît ne hésitez pas à ajouter du sel au goût:

public final class ComparisonTest { 

@Test 
public void compare() throws Exception { 
    String url = "your.url"; 
    String user = "your.user"; 
    String password = "your.password"; 
    // I am using Oracle here, but you can use any database 
    Connection connection = getConnection(url, user, password, OracleDriver.class); 

    ResultSet sourceResultSet = getResultSet(connection, "first_table"); 
    ResultSet targetResultSet = getResultSet(connection, "second_table"); 
    Map<Long, String> sourceIdHash = new HashMap<Long, String>(); 
    Map<Long, String> targetIdHash = new HashMap<Long, String>(); 

    try { 
     long rows = 0; 
     do { 
      if (sourceResultSet.next()) { 
       if (targetResultSet.next()) { 
        // Compare the lines 
        long sourceHash = hash(getRowValues(sourceResultSet, sourceResultSet.getMetaData())); 
        long targetHash = hash(getRowValues(targetResultSet, targetResultSet.getMetaData())); 

        sourceIdHash.put(sourceHash, sourceResultSet.getString(1)); 
        targetIdHash.put(targetHash, targetResultSet.getString(1)); 

        if (targetIdHash.containsKey(sourceHash)) { 
         targetIdHash.remove(sourceHash); 
         sourceIdHash.remove(sourceHash); 
        } 
        if (sourceIdHash.containsKey(targetHash)) { 
         sourceIdHash.remove(targetHash); 
         targetIdHash.remove(targetHash); 
        } 
       } else { 
        // Add the source row 
        long sourceHash = hash(getRowValues(sourceResultSet, sourceResultSet.getMetaData())); 
        sourceIdHash.put(sourceHash, sourceResultSet.getString(1)); 
       } 
      } else { 
       if (targetResultSet.next()) { 
        // Add the target row 
        long targetHash = hash(getRowValues(targetResultSet, targetResultSet.getMetaData())); 
        targetIdHash.put(targetHash, targetResultSet.getString(1)); 
       } else { 
        break; 
       } 
      } 
      if (rows++ % 10000 == 0) { 
       System.out.println("Rows : " + rows); 
      } 
     } while (true); 
    } finally { 
     closeAll(sourceResultSet); 
     closeAll(targetResultSet); 
    } 

    for (final Map.Entry<Long, String> mapEntry : sourceIdHash.entrySet()) { 
     if (targetIdHash.containsKey(mapEntry.getKey())) { 
      targetIdHash.remove(mapEntry.getKey()); 
      continue; 
     } 
     System.out.println("Not in target : " + mapEntry.getValue()); 
    } 
    for (final Map.Entry<Long, String> mapEntry : targetIdHash.entrySet()) { 
     if (sourceIdHash.containsKey(mapEntry.getKey())) { 
      sourceIdHash.remove(mapEntry.getKey()); 
      continue; 
     } 
     System.out.println("Not in source : " + mapEntry.getValue()); 
    } 

    System.out.println("In source and not target : " + sourceIdHash.size()); 
    System.out.println("In target and not source : " + targetIdHash.size()); 
} 

private ResultSet getResultSet(final Connection connection, final String tableName) { 
    String query = "select * from " + tableName + " order by pdb_key, organization_code, service_littera, day, resource_category"; 
    return executeQuery(connection, query); 
} 

private Object[] getRowValues(final ResultSet resultSet, final ResultSetMetaData resultSetMetaData) throws SQLException { 
    List<Object> rowValues = new ArrayList<Object>(); 
    for (int i = 2; i < resultSetMetaData.getColumnCount(); i++) { 
     rowValues.add(resultSet.getObject(i)); 
    } 
    return rowValues.toArray(new Object[rowValues.size()]); 
} 

private final Connection getConnection(final String url, final String user, final String password, final Class<? extends Driver> driverClass) { 
    try { 
     DriverManager.registerDriver(driverClass.newInstance()); 
     return DriverManager.getConnection(url, user, password); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

private final ResultSet executeQuery(final Connection connection, final String query) { 
    try { 
     return connection.createStatement().executeQuery(query); 
    } catch (SQLException e) { 
     throw new RuntimeException(e); 
    } 
} 

private final Long hash(final Object... objects) { 
    StringBuilder builder = new StringBuilder(); 
    for (Object object : objects) { 
     builder.append(object); 
    } 
    return hash(builder.toString()); 
} 

public Long hash(final String string) { 
    // Must be prime of course 
    long seed = 131; // 31 131 1313 13131 131313 etc.. 
    long hash = 0; 
    char[] chars = string.toCharArray(); 
    for (int i = 0; i < chars.length; i++) { 
     hash = (hash * seed) + chars[i]; 
    } 
    return Long.valueOf(Math.abs(hash)); 
} 

private void closeAll(final ResultSet resultSet) { 
    Statement statement = null; 
    Connection connection = null; 
    try { 
     if (resultSet != null) { 
      statement = resultSet.getStatement(); 
     } 
     if (statement != null) { 
      connection = statement.getConnection(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    close(resultSet); 
    close(statement); 
    close(connection); 
} 

private void close(final Statement statement) { 
    if (statement == null) { 
     return; 
    } 
    try { 
     statement.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private void close(final Connection connection) { 
    if (connection == null) { 
     return; 
    } 
    try { 
     connection.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private void close(final ResultSet resultSet) { 
    if (resultSet == null) { 
     return; 
    } 
    try { 
     resultSet.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

}