Correctly delete duplicates in the list

Given the following type of data Testcase( XQuery, Testpath, FirstInputFile, SecondInputFile, Expected)

how to remove duplicates.

Duplicate Definition:

If FirstInputFilealready on the list, SecondInputFilevice versa.

Here is Testdata p>

tcs.add(new HeaderAndBodyTestcase("XQ 1", "/1", "FAIL", "FAIL2", "FAILED"));
    tcs.add(new HeaderAndBodyTestcase("XQ 1", "/1", "FAIL2", "FAIL", "FAILED"));
    tcs.add(new HeaderAndBodyTestcase("XQ 2", "/2", "FAIL4", "FAIL3", "FAILED2"));
    tcs.add(new HeaderAndBodyTestcase("XQ 2", "/2", "FAIL3", "FAIL4", "FAILED2"));

and here is the function

 protected void deleteExistingDuplicatesInArrayList(final ArrayList<HeaderAndBodyTestcase> list) {


    for (int idx = 0; idx < list.size() - 1; idx++) {

        if (list.get(idx).firstInputFile.equals(list.get(idx).secondInputFile)
                || (list.get(idx + 1).firstInputFile.equals(list.get(idx).firstInputFile)
                        && list.get(idx).secondInputFile.equals(list.get(idx + 1).secondInputFile)
                        || (list.get(idx).firstInputFile.equals(list.get(idx + 1).secondInputFile)
                                && list.get(idx).secondInputFile.equals(list.get(idx + 1).firstInputFile)))) {
            list.remove(idx);
        }

    }

}

This solution is already working, but it seems very crappy, so is there a better solution for this?

+4
source share
3 answers

Given your rather specific limitations of "equality", I think the best way is to support two sets of first and second input files already seen and a loop:

Set<String> first = new HashSet<>();
Set<String> second = new HashSet<>();
for (HeaderAndBodyTestcase tc : tcs) {
    if (! first.contains(tc.getSecondInputFile()) && 
            ! second.contains(tc.getFirstInputFile())) {
        first.add(tc.getFirstInputFile());
        second.add(tc.getSecondInputFile());
        System.out.println(tc); // or add to result list
    }
}

This will also work if “equal” items are not displayed immediately after each other in the original list.

, . , , , Iterator remove.


(, , ), , , :

  • , ( )
  • , , -
  • , , ,
  • ( )

, , , , ( "", "" ). , Iterator last, , .

HeaderAndBodyTestcase last = null;
for (Iterator<HeaderAndBodyTestcase> iter = list.iterator(); iter.hasNext();) {
    HeaderAndBodyTestcase curr = iter.next();
    if (curr.firstInputFile.equals(curr.secondInputFile)) {
        iter.remove();
    }
    if (last != null) {
        boolean bothEqual = curr.firstInputFile.equals(last.firstInputFile) 
                         && curr.secondInputFile.equals(last.secondInputFile);
        boolean crossedEqual = curr.secondInputFile.equals(last.firstInputFile)
                            && curr.firstInputFile.equals(last.secondInputFile);
        if (bothEqual || crossedEqual) {
            iter.remove();
        }
    }
    last = curr;
}
+1

Set , , , ( )

Set<HeaderAndBodyTestcase> set = new Hashset<>(list);
+2

If you are using java 8, you can simply:

tcs = list.stream().distinct().collect(Collectors.toList());

This will only work if HeaderAndBodyTestcase.equals(HeaderAndBodyTestcase)properly redefined.

Without java 8 you can do:

Set<HeaderAndBodyTestcase> set = new HashSet<>(list);
List<HeaderAndBodyTestcase> tcs = new ArrayList<>(set);
+1
source

Source: https://habr.com/ru/post/1695986/


All Articles