簡體   English   中英

比較兩個集合,比較兩個文本文件的添加,刪除和修改

[英]comparing two collections for comparing two text files for additions, deletions, modifications

我有以下兩個收藏夾,其中包含學生證。

id是格式為111-1111的字符串。 例如ID 221-2534、215-6365等。

 Collection<String> newKeys = new ArrayList<String>();
 Collection<String> oldKeys = new ArrayList<String>();

這些ID與其他數據一起位於固定格式的文件中。 也就是說,前8個字符ID,后10個字符名稱,后10個字符地址,等等。

我將id讀入集合,如下所示:

String oldFile = "C:\\oldFile.dat";
String newFile = "C:\\newFile.dat";
BufferedReader in;
String str;
// Read keys from old file
in = new BufferedReader(new FileReader(oldFile));
while ((str = in.readLine()) != null) {
      oldKeys.add(str.substring(0, 8).trim());
}
in.close();

// Read keys from new file
in = new BufferedReader(new FileReader(newFile));
while ((str = in.readLine()) != null) {
    newKeys.add(str.substring(0, 8).trim());
}
in.close();   

此處,文件中的條目按SSN排序。 因此,我相信所形成的集合也將得到排序。

現在:

案例:我想通過比較兩個集合來了解差異作為結果列表。 那就是我需要的列表,其中包含添加的條目,刪除的條目和相同的條目。

然后,我將使用具有公共條目的列表從這兩個文件中讀取相應的數據,並進行比較以進行任何修改。

那是我有了共同的清單之后

a)從列表中獲取一個ID。 從兩個文件中讀取該ID的對應數據為字符串。 比較字符串是否有任何差異。 如果有所不同,請將newFile字符串移動到fileWithUpdates中。

b)在沒有差異的情況下什么也不做。

問題:

1)這是正確的方法嗎?

2)還有如何比較兩個集合以獲得結果列表。 toBeDeleted,toBeAdded和sameEntries?

3)如何從鍵上的文件中讀取特定行(在這種情況下為學生ID)?

更新:

根據以下答案,添加以下代碼:

Iterator<String> iOld = oldKeys.iterator();
    Iterator<String> iNew = newKeys.iterator();
    Map<String, String> tempMap = new HashMap<String, String>();

    while (iOld.hasNext()) {
        tempMap.put(iOld.next(), "old");
    }

    while (iNew.hasNext()) {
        String temp = iNew.next();
        if (tempMap.containsKey(temp)) {
            tempMap.put(temp, "both");
        }

        else {
            System.out.println("here");
            tempMap.put(temp, "new");
        }
    }

所以現在我有一張地圖了:

要比較的條目上圖中值為“兩者”的條目

要添加的條目上圖中值為“新”的條目

要刪除的條目上圖中值為“舊”的條目

所以我的問題歸結為:

如何從密鑰上的文件中讀取特定行,以便我可以比較它們以進行數據修改?

謝謝閱讀!

總體而言,我認為這不是正確的方法。 與其將所有信息存儲在單個String中,不如創建一個對象,其中包含用於存儲您需要存儲的各種內容的字段。

public Student {
   String id; //or int, or char[8]
   String firstName, lastName;
   String address;
  //and so on

  //constructor - Given a line of input from the data file, create a Student object
  public Student(String line) {
     id = line.substring(0,8);
     //and so on

  }

至於比較兩個集合,讓我們將它們都聲明為ArrayLists,然后跟蹤它們的共同點的索引。

ArrayList<String> newKeys = new ArrayList<>();  //java 7 syntax
ArrayList<String> oldKeys = new ArrayList<>();
//store keys from files.

TreeMap<Integer, Integer> commonKeys = new TreeMap<Integer, Integer>();
//stores the index values from newList as keys that get mapped to the old list index.

ArrayList<Integer> removedKeys =ArrayList<>();  
// Store the indices from oldKeys that are not in newKeys.

int newListIndex = 0;
int oldListIndex = 0;
while(newListIndex < newKeys.size() && oldListIndex<oldKeys.size()) {
   if(newKeys.get(newListIndex).equals(oldKeys.get(oldListIndex) ) {
      commonKeys.put(newListIndex,oldListIndex);
      oldListIndex++; newListIndex++ 
   }
   else if(newKeys.get(newListIndex).compareTo(oldKeys.get(oldListIndex)>0 ) {
      removedKeys.add(oldListIndex);
      oldListIndex++
   }
   else {
      //maybe this is a newListIndex that is not in the old list, so it was added.
      newListIndex++;
   }
}

您將需要稍微調整上面的代碼以使其失效保護。 另一種方法是使用包含方法,如下所示:

for(int i=0; i<oldKeys.size(); i++) {
   String oldKey = oldKeys.get(i);
   if(newKeys.contians(oldKey);
       commonKeys.put(newKeys.indexOf(oldKey) , i);
   else
       removedKeys.add(i);

}

如果文件不太大,也許可以執行以下步驟

  • 創建一個HashMap
  • 對於舊文件中的每個條目,將其添加為值“ Old”
  • 對於新文件中的每個條目,
    • 檢查它是否在HashMap中
      • 如果是這樣,則設置值“ Both”(此外,您可以將其添加到公共元素的HashMap中)
      • 如果不是,則將其添加為值“ New”

希望它可以解決問題2。請告訴我它是否有效。 謝謝!

你可以這樣下去

Collection<String> newKeys = new ArrayList<String>();  
Collection<String> oldKeys = new ArrayList<String>(); 

Collection<String> toBeDeleted = new ArrayList(oldKeys).removeAll(newKeys);
Collection<String> toBeAdded = new ArrayList(newKeys).removeAll(oldKeys);

Collection<String> sameEntries = new ArrayList(newKeys).removeAll(toBeAdded);

盡管對於第三個問題,最好使用HashMap(如果希望自動對鍵進行排序,則最好使用TreeMap)。

***更新

在原始文件讀取代碼中,您可以進行以下更改,

Map<String, String> oldContentMap = new HashMap<String, String>();  
while ((str = in.readLine()) != null) {       
    oldKeys.add(str.substring(0, 8).trim()); 
    oldContentMap.put(str.substring(0, 8).trim(),str.substring(8).trim());
} 
in.close(); 

對於新文件,

  Map<String, String> newContentMap = new HashMap<String, String>();  
    while ((str = in.readLine()) != null) {       
        newKeys.add(str.substring(0, 8).trim()); 
        newContentMap.put(str.substring(0, 8).trim(),str.substring(8).trim());
    } 
    in.close(); 

現在您可以進行比較了,

for (Map.Entry<String, String> entry : tempMap.entrySet()) { 
    if(entry.getValue().equals("both"){ //comparing for keys in both lists
         String oldContent = oldContentMap.get(entry.getKey());
         String newContent = newContentMap.get(entry.getKey());
         if(oldContent.equals(newContent)){
            System.out.println("Different data for key:"+entry.getKey());
         }
    }
}

您可以使用必要的temp變量,也可以將聲明移到循環外。

我會這樣做

  • 為每個文件(oldFile,newFile)創建兩個HashMap,您的ID將是地圖的鍵
  • 構建新的數組列表:common,toBeAdded,toBeDeleted
  • 在oldKeysHashMap密鑰上循環:對於每個密鑰,檢查密鑰是否存在於newHasMap中。 如果是,請檢查兩個鍵是否包含相同的值(使用Maps很容易)->將條目放入公共arraylist中。 如果否,則將條目放入toBeDeleted。
  • 在newKeysHashMap上循環並填寫toBeAdded arrayList
  • 將toBeAdded和Common arraysList混合在一個新的列表中。 刪除兩個原始文件。 編寫一個新文件,並使用新的混合arrayList的條目填充該文件。 (與在文件中搜索ID並刪除行相比,刪除和創建新文件應該更加快捷)

我還可以提供一些代碼片段。 如果需要,請使用Map界面的實現來對條目進行排序。 HashMap並非如此,SortedHashMap可能是正確的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM