Перепробовал несколько разных способов...
Прилагаю сюда один из последних - на цикле while:
1. получили два ArrayList - fileSource - исходный файл и fileUpdated - список с обновлёнными данными.
2. цикл запускается с нулевым итератором с проверкой на размер обоих листов
3. Если первые элементы равны - удаляем их и переходим на следующую итерацию не увеличивая счётчик цикла
4. Если элементы не равны, то изменённую строку сравниваем со следующей строкой из списка источника. Если они равны, то удаляем строку из исходного списка и переходим на следующую итерацию.
5. Если строки не равны и если следующая строка источника не равна текущей изменённой, то это значит, что была добавлена новая строка. Удаляем строку из списка с изменёнными строками - идём на следующую итерацию.
Сворачивайте закомментированные блоки, чтобы не мешались.
Буду признателен за любые мысли
package com.javarush.task.task19.task1916;
import java.io.*;
import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.List;
/*
Отслеживаем изменения
*/
public class Solution {
public static List<LineItem> lines = new ArrayList<LineItem>();
public static void main(String[] args) {
String fileNameSource = "", fileNameUpdated = "",
sourceLine = "", updatedLine = "";
List<LineItem> lines = new ArrayList<>();
List<String> fileSource = new ArrayList<>(), fileUpdated = new ArrayList<>();
int maxListSize = 0, temp = 0, k = 0;
try (BufferedReader buffReader = new BufferedReader(new InputStreamReader(System.in))) {
fileNameSource = buffReader.readLine();//"C:\\Users\\sesa292574\\Desktop\\Hobby\\f1.txt"; //buffReader.readLine();//
fileNameUpdated = buffReader.readLine();//"C:\\Users\\sesa292574\\Desktop\\Hobby\\f2.txt"; //buffReader.readLine();
} catch (IOException e) {
System.out.println(e);
} // end try
// -------------------------- reading from files ----------------------------------------
/*
try(FileReader fileSourceReader = new FileReader(fileNameSource);
FileReader fileUpdatedReader = new FileReader(fileNameUpdated)){
while((count = fileSourceReader.read()) != -1) {
buffer += (char) count;
if ((char) count == '\n') {
fileSource.add(buffer.replaceAll("\r\n",""));
buffer = "";
}
}// end while
if (fileSource.isEmpty() || !buffer.equals(fileSource.get(fileSource.size()-1)))
fileSource.add(buffer);
buffer = "";
while((count = fileUpdatedReader.read()) != -1) {
buffer += (char) count;
if ((char) count == '\n') {
fileUpdated.add(buffer.replaceAll("\r\n",""));
buffer = "";
}
}// end while
if (fileUpdated.isEmpty() || !buffer.equals(fileUpdated.get(fileUpdated.size()-1)))
fileUpdated.add(buffer);
} catch (IOException e) {
System.out.println(e);
} // end try
*/
try (BufferedReader buffReaderSource = new BufferedReader(new FileReader(fileNameSource));
BufferedReader buffReaderUpd = new BufferedReader(new FileReader(fileNameUpdated))) {
while (buffReaderSource.ready())
fileSource.add(buffReaderSource.readLine());
while (buffReaderUpd.ready())
fileUpdated.add(buffReaderUpd.readLine());
} catch (IOException e) {
e.printStackTrace();
}
// ------------------------- End of reading from files -------------------------------
/*// ------------------------- Add the empty lines to the smallest ArrayList -------------
if (fileSource.size() < fileUpdated.size()) {
temp = fileUpdated.size() - fileSource.size();
for (int i = 0; i < temp; i++)
fileSource.add("");
} else if (fileSource.size() > fileUpdated.size()) {
temp = fileSource.size() - fileUpdated.size();
for (int i = 0; i < temp; i++)
fileUpdated.add("");
}*/
// ------------------------ Matching the lines and setting up the right status into result list----------
/* if(fileSource.size() >= fileUpdated.size())
maxListSize = fileSource.size();
else maxListSize = fileUpdated.size();
for (int i = 0; i < maxListSize; i++) {
if(i == fileSource.size()){
lines.add(new LineItem(Type.ADDED,fileUpdated.get(i)));
break;
}
else if( i == fileUpdated.size()){
lines.add(new LineItem(Type.REMOVED,fileSource.get(i)));
break;
}
sourceLine = fileSource.get(i);
updatedLine = fileUpdated.get(i);
*//* not changed *//*
if (sourceLine.equals(updatedLine))
lines.add(new LineItem(Type.SAME, sourceLine));
*//* removed *//*
else if (i != fileSource.size()-1 && updatedLine.equals(fileSource.get(i+1))) {
lines.add(new LineItem(Type.REMOVED, sourceLine));
fileUpdated.add(i, "");
maxListSize++;
}
*//* added *//*
else {
lines.add(new LineItem(Type.ADDED, updatedLine));
fileSource.add(i,"");
maxListSize++;
}
}// end for*/
while(k < fileSource.size() && k< fileUpdated.size()){
sourceLine = fileSource.get(k);
updatedLine = fileUpdated.get(k);
/* not changed */
if (sourceLine.equals(updatedLine)) {
lines.add(new LineItem(Type.SAME, sourceLine));
fileSource.remove(k);
fileUpdated.remove(k);
continue;
}
/* removed */
else if (updatedLine.equals(fileSource.get(k+1))) {
lines.add(new LineItem(Type.REMOVED, sourceLine));
fileSource.remove(k);
continue;
}
/* added */
else {
lines.add(new LineItem(Type.ADDED, updatedLine));
fileUpdated.remove(k);
continue;
}
}// end while
if (fileSource.size() > 0){
lines.add(new LineItem(Type.REMOVED,fileSource.get(0)));
} else if (fileUpdated.size() >0) {
lines.add(new LineItem(Type.ADDED,fileUpdated.get(0)));
}
// print result list
for (LineItem li: lines) {
System.out.println(li.type + "\t" + li.line);
}
}// end main
public static enum Type {
ADDED, //добавлена новая строка
REMOVED, //удалена строка
SAME //без изменений
} // end ENUM
public static class LineItem {
public Type type;
public String line;
public LineItem(Type type, String line) {
this.type = type;
this.line = line;
}
} // end LineItem
}
/*
Отслеживаем изменения
Считать с консоли 2 имени файла - file1, file2.
Файлы содержат строки, file2 является обновленной версией file1, часть строк совпадают.
Нужно создать объединенную версию строк, записать их в список lines.
Операции ADDED и REMOVED не могут идти подряд, они всегда разделены SAME.
Пустые строки даны в примере для наглядности.
В оригинальном и редактируемом файлах пустых строк нет!
Пример 1:
оригинальный редактированный общий
file1: file2: результат:(lines)
строка1 строка1 SAME строка1
строка2 REMOVED строка2
строка3 строка3 SAME строка3
строка4 REMOVED строка4
строка5 строка5 SAME строка5
строка0 ADDED строка0
строка1 строка1 SAME строка1
строка2 REMOVED строка2
строка3 строка3 SAME строка3
строка4 ADDED строка4
строка5 строка5 SAME строка5
строка0 REMOVED строка0
Пример 2:
оригинальный редактированный общий
file1: file2: результат:(lines)
строка1 строка1 SAME строка1
строка0 ADDED строка0
Пустые строки в примере означают, что этой строки нет в определенном файле.
Требования:
1. Класс Solution должен содержать класс LineItem.
2. Класс Solution должен содержать enum Type.
3. Класс Solution должен содержать публичное статическое поле lines типа List<LineItem>,
которое сразу проинициализировано.
4. В методе main(String[] args) программа должна считывать имена файлов с консоли (используй BufferedReader).
5. В методе main(String[] args) BufferedReader для считывания данных с консоли должен быть закрыт.
6. Программа должна считывать содержимое первого и второго файла (используй FileReader).
7. Потоки чтения из файлов (FileReader) должны быть закрыты.
8. Список lines должен содержать объединенную версию строк из файлов, где для каждой строки указана одна из операций ADDED, REMOVED, SAME.
*/