Eliminar líneas duplicadas de texto usando Java

Me preguntaba si alguien tiene lógica en java que elimine líneas duplicadas mientras mantiene el orden de las líneas.

Preferiría ninguna solución de expresiones regulares.

public class UniqueLineReader extends BufferedReader { Set lines = new HashSet(); public UniqueLineReader(Reader arg0) { super(arg0); } @Override public String readLine() throws IOException { String uniqueLine; if (lines.add(uniqueLine = super.readLine())) return uniqueLine; return ""; } //for testing.. public static void main(String args[]) { try { // Open the file that is the first // command line parameter FileInputStream fstream = new FileInputStream( "test.txt"); UniqueLineReader br = new UniqueLineReader(new InputStreamReader(fstream)); String strLine; // Read File Line By Line while ((strLine = br.readLine()) != null) { // Print the content on the console if (strLine != "") System.out.println(strLine); } // Close the input stream in.close(); } catch (Exception e) {// Catch exception if any System.err.println("Error: " + e.getMessage()); } } } 

Versión modificada:

 public class UniqueLineReader extends BufferedReader { Set lines = new HashSet(); public UniqueLineReader(Reader arg0) { super(arg0); } @Override public String readLine() throws IOException { String uniqueLine; while (lines.add(uniqueLine = super.readLine()) == false); //read until encountering a unique line return uniqueLine; } public static void main(String args[]) { try { // Open the file that is the first // command line parameter FileInputStream fstream = new FileInputStream( "/home/emil/Desktop/ff.txt"); UniqueLineReader br = new UniqueLineReader(new InputStreamReader(fstream)); String strLine; // Read File Line By Line while ((strLine = br.readLine()) != null) { // Print the content on the console System.out.println(strLine); } // Close the input stream in.close(); } catch (Exception e) {// Catch exception if any System.err.println("Error: " + e.getMessage()); } } } 

Si alimenta las líneas en un LinkedHashSet , ignora las repetidas, ya que es un conjunto, pero conserva el orden, ya que está vinculado. Si solo quiere saber si ha visto una línea dada anteriormente, aliméntelos en un Set simple a medida que avanza e ignore aquellos que ya contiene / contiene.

Lea el archivo de texto con un BufferedReader y guárdelo en un LinkedHashSet. Imprimir de nuevo.

Aquí hay un ejemplo:

 public class DuplicateRemover { public String stripDuplicates(String aHunk) { StringBuilder result = new StringBuilder(); Set uniqueLines = new LinkedHashSet(); String[] chunks = aHunk.split("\n"); uniqueLines.addAll(Arrays.asList(chunks)); for (String chunk : uniqueLines) { result.append(chunk).append("\n"); } return result.toString(); } } 

Aquí hay algunas pruebas unitarias para verificar (ignorar mi malvado copiar y pegar):

 import org.junit.Test; import static org.junit.Assert.*; public class DuplicateRemoverTest { @Test public void removesDuplicateLines() { String input = "a\nb\nc\nb\nd\n"; String expected = "a\nb\nc\nd\n"; DuplicateRemover remover = new DuplicateRemover(); String actual = remover.stripDuplicates(input); assertEquals(expected, actual); } @Test public void removesDuplicateLinesUnalphabetized() { String input = "z\nb\nc\nb\nz\n"; String expected = "z\nb\nc\n"; DuplicateRemover remover = new DuplicateRemover(); String actual = remover.stripDuplicates(input); assertEquals(expected, actual); } } 

Aquí hay otra solución. ¡Solo usemos UNIX!

 cat MyFile.java | uniq > MyFile.java 

Edit: Oh, espera, vuelvo a leer el tema. ¿Es esta una solución legal ya que logré ser agnóstico del lenguaje?

Puede ser fácil eliminar la línea duplicada del texto o el archivo utilizando la nueva API de Stream de Java. Stream admite diferentes características agregadas como clasificación, distinción y trabajo con diferentes estructuras de datos existentes de Java y sus métodos. El siguiente ejemplo se puede usar para eliminar duplicados u ordenar el contenido en un archivo usando Stream API

 package removeword; import java.io.IOException; import java.nio.file.Files; import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Scanner; import java.util.stream.Stream; import static java.nio.file.StandardOpenOption.*; import static java.util.stream.Collectors.joining; public class Java8UniqueWords { public static void main(String[] args) throws IOException { Path sourcePath = Paths.get("C:/Users/source.txt"); Path changedPath = Paths.get("C:/Users/removedDouplicate_file.txt"); try (final Stream lines = Files.lines(sourcePath ) // .map(line -> line.toLowerCase()) /*optional to use existing string methods*/ .distinct() // .sorted()) /*aggregrate function to sort disctincted line*/ { final String uniqueWords = lines.collect(joining("\n")); System.out.println("Final Output:" + uniqueWords); Files.write(changedPath , uniqueWords.getBytes(),WRITE, TRUNCATE_EXISTING); } } } 

Para un rendimiento mejor / óptimo, es aconsejable utilizar las características de API de Java 8 a saber. Streams & Method hace referencia a LinkedHashSet for Collection como se muestra a continuación:

 import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Paths; import java.util.LinkedHashSet; import java.util.stream.Collectors; public class UniqueOperation { private static PrintWriter pw; enter code here public static void main(String[] args) throws IOException { pw = new PrintWriter("abc.txt"); for(String p : Files.newBufferedReader(Paths.get("C:/Users/as00465129/Desktop/FrontEndUdemyLinks.txt")). lines(). collect(Collectors.toCollection(LinkedHashSet::new))) pw.println(p); pw.flush(); pw.close(); System.out.println("File operation performed successfully"); } 

Aquí estoy usando un hashset para almacenar líneas vistas

 Scanner scan;//input Set lines = new HashSet(); StringBuilder strb = new StringBuilder(); while(scan.hasNextLine()){ String line = scan.nextLine(); if(lines.add(line)) strb.append(line); }