2010-02-28 88 views
0

我必須比較兩個表並告訴用戶兩個表之間的區別是什麼。在Java中比較兩個表

表1

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

表2

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

比較信息
正如你在表1看到代碼c1標籤bartext1和代碼d1標籤bartext2。 他們同樣期待最後一個字。除了最後一個字符外,我必須在我的報告中說明它們是相同的。表格中有幾行可能有額外的單詞或特殊字符,並且其位置在任何地方。不知何故,我必須告訴在報告中,兩個標籤都是相同的,期望單詞丟失或者其中一個單詞中有特殊字符。代碼在報告中並不重要。

更多信息
這個數據是從第三方party.Code未來永遠是獨一無二的,他們是沒有重複的代碼。 這可能是兩個代碼具有相似的值 像

代碼|標籤

ER4 |我有一個兄弟

WE3 |我有一個弟弟

預期的輸出應該是

  1. 標籤就在兩個表不同。 Table1標籤是:b1text和Tabl2標籤是:b2text。
  2. 標籤在兩個表中不同。 Table1標籤是:bartext1和Tabl2標籤是:bartext2。
  3. 表2中缺少標籤foo。
  4. 表格1中缺少標籤欄。
+0

您是否期望我們完整的源代碼具有單元測試和安裝腳本? – Roman 2010-02-28 22:08:33

+0

表已經排序了嗎?是否允許重複代碼?您是否允許使用Google Collections,Jakarta Common Collections等圖書館例程,或者是否完成此作業? – Fortyrunner 2010-02-28 22:08:56

+0

表已經排序了嗎? NO 是否允許複製代碼? NO 使用庫例程,例如Google Collections,Jakarta Common Collections?YES 正在做作業嗎? NO – NETQuestion 2010-02-28 22:19:59

回答

2

我想爲這個Table對象創建一個抽象,它有一個可以隱藏客戶端所有細節的equals實現。 Java是一種面向對象的語言,所以最好使用對象作爲其存在的理由。

+0

@duffymo一般來說很好,但'equals()'應該給出'true'或'false'作爲輸出,而不是上面描述的那個。因此,對於這個特定的任務,人們不得不實施不同的比較算法。 – 2010-02-28 22:19:04

+0

因此,如果您需要返回原因碼列表,請編寫另一種方法。 「用物體思考」的觀點依然存在。 – duffymo 2010-02-28 22:27:56

1

有一個開源的Java框架,做的是:

www.diffkit.org

1

這爲我工作,請隨時加鹽調味:

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

}