сравнение двух коллекций для сравнения двух текстовых файлов для добавления, удаления, модификации - PullRequest
1 голос
/ 19 марта 2012

У меня есть две коллекции, как показано ниже, которые содержат идентификаторы для студентов.

Идентификаторы - это строки в формате 111-1111.например, идентификаторы 221-2534, 215-6365 и т. д.

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

Идентификаторы находятся в файле фиксированного формата вместе с другими данными.Это первые 8 символов, следующие 10 символов, следующие 10 символов и т. Д.

Я читаю идентификаторы в коллекцию, как показано ниже:

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) Возьмите идентификатор из списка.Считайте соответствующие данные для этого идентификатора из обоих файлов в строки.Сравните строку для любых различий.В случае различий, переместите строку newFile в файл с обновлениями.

b) Ничего не делайте в случае отсутствия различий.

Вопросы:

1) Это правильный подход?

2) Также, как сравнить две коллекции, чтобы получить результирующие списки, а именно.toBeDeleted, toBeAdded и sameEntries?

3) Как прочитать определенную строку из файла на ключе (в данном случае идентификатор студента)?

Обновить:

Основываясь на ответе ниже, добавил следующий код:

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

Так что теперь у меня есть карта, которая имеет:

Записи должны бытьдля сравнения: Записи в приведенной выше карте со значением "both"

Записи для добавления: Записи в вышеуказанной карте со значением "new"

Записиподлежит удалению: Записи в приведенной выше карте со значением "old"

Итак, моя проблема сводится к:

Как прочитать определенную строку из файла на ключе, чтобы яможете сравнить их по модификации данных ??

Спасибо за чтение!

Ответы [ 4 ]

1 голос
/ 19 марта 2012

В целом, я не думаю, что это правильный подход.Вместо того, чтобы хранить всю информацию в одной строке, я бы создал объект с полями для различных вещей, которые нужно хранить.

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

}
0 голосов
/ 19 марта 2012

Я бы выполнил вашу задачу таким образом

  • Создайте два HashMap по одному для каждого файла (oldFile, newFile), ваши идентификаторы станут ключами карты
  • Создание новых массивов: общие, toBeAdded, toBeDeleted
  • цикл для ключей oldKeysHashMap: для каждого ключа проверьте, существует ли ключ в newHasMap. Если да, проверьте, содержат ли два ключа одно и то же значение (это легко сделать с помощью Карт) -> поместите запись в общий список. Если нет, поместите запись в toBeDeleted.
  • цикл newKeysHashMap и заполнение списка массивов toBeAdded
  • Смешайте toBeAdded и Common arraysList в новый. Удалите два оригинальных файла. Написать новый файл и заполнить файл с записями нового смешанного arrayList. (удаление и создание нового файла должно быть более быстрым, чем поиск идентификаторов в файле и удаление строки)

Я также могу предоставить фрагмент кода. Если вам нужно использовать реализацию интерфейса Map, которая сохраняет запись отсортированной. Это не тот случай HashMap, SortedHashMap может быть правильным.

0 голосов
/ 19 марта 2012

Вы могли бы продолжить так,

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

вы можете использовать необходимую временную переменную и также перемещать объявления вне цикла ..

0 голосов
/ 19 марта 2012

Если ваши файлы не слишком велики, возможно, вы можете сделать следующие шаги

  • Создать HashMap
  • Для каждой записи в старом файле добавьте ее со значением 'Old'
  • Для каждой записи в новом файле
    • Проверьте, есть ли она в HashMap
      • Если так, тогда установите значение «Оба» (Кроме того, вы можете добавить его вHashMap общих элементов)
      • Если нет, добавьте его со значением 'New'

Надеемся, что это должно ответить на вопрос 2. Пожалуйстадайте мне знать, если это работает.Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...