2013-06-02 6 views
20

Я пытаюсь читать из двух файлов и хранить их в двух отдельных arraylists. Файлы состоят из слов, которые являются либо отдельными по строке, либо несколькими словами, разделенными запятыми. я прочитал каждый файл со следующим кодом (не полным):Удалить все объекты в arraylist, которые существуют в другом arraylist

ArrayList<String> temp = new ArrayList<>(); 

FileInputStream fis; 
fis = new FileInputStream(fileName); 

Scanner scan = new Scanner(fis); 

while (scan.hasNextLine()) { 
    Scanner input = new Scanner(scan.nextLine()); 
    input.useDelimiter(","); 
    while (scan.hasNext()) { 
     String md5 = scan.next(); 
     temp.add(md5); 
    } 
} 
scan.close();  

return temp; 

мне теперь нужно читать два файл и удалить все слова из первого файла, который также существует во втором файле (есть некоторые повторяющиеся слова в файлах). Я пробовал использовать for-loops и другие подобные вещи, но ничего не сработало, поэтому любая помощь будет принята с благодарностью!

Вопрос о бонусе: мне также нужно выяснить, сколько дубликатов есть в двух файлах - я сделал это, добавив оба arraylists в HashSet, а затем вычитая размер набора из объединенного размера двух arraylists - это хорошее решение, или это можно сделать лучше?

+0

Возможный дубликат [Вычитание один ArrayList из других Список_массивов] (http://stackoverflow.com/questions/9933403/subtracting-one-arraylist-from-another-arraylist) –

ответ

28

Вы можете использовать метод removeAll для удаления элементов из одного списка из другого списка.

Для получения дубликатов можно использовать метод retainAll, хотя ваш подход с набором также хорошо (и, вероятно, более эффективным)

+0

Спасибо! Я пробовал использовать removeAll так: ArrayList file1 = readFile (fileName1); ArrayList file2 = readFile (fileName2); file1.removeAll (file2); return file1; Любая идея, почему это не работает? – GeorgeWChubby

+0

Ваша проблема должна быть в другом месте. Попробуйте распечатать содержимое файлов file1, file2 и file1 после операции удаления, чтобы увидеть, что происходит. – Joni

+0

Проблема в том, что операция removeAll делает всю вещь зависающей.Я разрешил ему работать в течение 50 минут, и ничего не произошло - все, что я делаю, пока не назову метод, работает нормально (и если я удалю операцию removeAll, метод отлично работает). Буквально единственное, что не работает, это removeAll, что меня смущает. – GeorgeWChubby

6

Коллекции объект имеет удобный способ для этой цели:

list1.removeAll(list2); 
2

Как уже упоминалось, используется метод Collection.removeAll, если вы хотите, чтобы удалить все элементы которые существуют в одной коллекции из коллекции, которую вы вызываете removeall.

Что касается вашего бонусного вопроса, я являюсь огромным поклонником класса Guava Sets. Я хотел бы предложить использовать Sets.intersection следующим образом:

Sets.intersection(wordSetFromFile1, wordSetFromFile2).size(); 

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

2

Прежде всего, необходимо переопределить метод, равный в пользовательском классе и определить критерии согласования удаления лист

public class CustomClass{ 

@Override 
    public boolean equals(Object obj) { 

     try { 
      CustomClass licenceDetail = (CustomClass) obj; 
      return name.equals(licenceDetail.getName()); 
     } 
     catch (Exception e) 
     { 
      return false; 
     } 

    } 
} 

Во-вторых вызове метода RemoveAll()

list1.removeAll (песни2) ;

+1

Упрощение этого, поскольку это единственный ответ, в котором явно упоминается, что метод equals должен быть переопределен в классах, которые находятся в списках. Это может быть не очевидно для некоторых людей и removeAll просто не будет работать так, как ожидалось, если equals не реализовано правильно для ваших пользовательских классов. – ioss

Смежные вопросы