Java. How can I check if element was successfully added in set and tracking indexes with forEach?












0















I need to find non similar rows in matrix and return set of such rows.



A rows is said to be similar if the sets of numbers occurring in these rows coincide.



Example:
origin:



1 2 2 4 4
4 2 1 4
3 2 4 1 5 8


expected result:



1 2 2 4 4
3 2 4 1 5 8


My ideas:



Clean duplicates from each row via convert two dimensional array to List>



Create new set of int and add row then if row was added its means that row is non similar.then record number of row. return created new set of rows of origin matrix.
I know that I can check if element was added via Boolean return value of Add method of Set.
But there is problem by forEach, that don't provide index. And I can't use expressions inside forEach. What should I do?



My code:



class NonSimilar {
private int matrix;
private List<Set<Integer>> rows = new ArrayList<>();

public NonSimilar (int matrix) {
this.matrix = matrix;
for (int i = 0; i < matrix.length; i++) {
rows.add(Arrays.stream(matrix[i]).boxed().collect(Collectors.toSet()));
}
}

public Set<int> getNonSimilarRows() {
Set<Set<Integer>> nonSimularRows = new HashSet<>();
rows.forEach(item -> nonSimularRows.add(item));
// Now I have to check successfully added rows numbers and construct new Set from Origin matrix
return new HashSet<int>();
}
}


Ok. I replaced forEach with for iteration and now all works correctly.



  public Set<int> getNonSimilarRows() {
Set<Set<Integer>> nonSimularRows = new HashSet<>();
//rows.forEach(item -> nonSimularRows.add(item));
int index = -1;
ArrayList<Integer> indexes = new ArrayList<>();
for (Set<Integer> item : rows) {
index++;
if (nonSimularRows.add(item)) {
indexes.add(index);
}
}
HashSet<int> newSet = new HashSet<int>();
for (Integer item : indexes) {
newSet.add(matrix[item]);
}
return newSet;
}


Anyway code looks very ugly and I want to get advice how I can refactor code with modern approaches like forEach and Stream API.










share|improve this question

























  • why is the expected result 1 2 2 4 4 and 3 2 4 1 5 8 but not 4 2 1 4 ?

    – Aomine
    Dec 30 '18 at 15:00






  • 1





    @Aomine I believe 1 2 2 4 4 contain the same elements as 4 2 1 4 when broken down to a set. Both would be {1, 2, 4}. I'm assuming the OP wants to the keep the first one found. Correct me If I'm wrong.

    – RoadRunner
    Dec 30 '18 at 15:02













  • Because first and second rows are similar, but first and third are not. I need to get not similar rows.

    – Dmitry Sokolov
    Dec 30 '18 at 15:03











  • Please define how the rows are similar. Is the similarity based on what RoadRunner said?

    – IPat
    Dec 30 '18 at 15:05











  • A rows is said to be similar if the sets of numbers occurring in these rows coincide

    – Dmitry Sokolov
    Dec 30 '18 at 15:12
















0















I need to find non similar rows in matrix and return set of such rows.



A rows is said to be similar if the sets of numbers occurring in these rows coincide.



Example:
origin:



1 2 2 4 4
4 2 1 4
3 2 4 1 5 8


expected result:



1 2 2 4 4
3 2 4 1 5 8


My ideas:



Clean duplicates from each row via convert two dimensional array to List>



Create new set of int and add row then if row was added its means that row is non similar.then record number of row. return created new set of rows of origin matrix.
I know that I can check if element was added via Boolean return value of Add method of Set.
But there is problem by forEach, that don't provide index. And I can't use expressions inside forEach. What should I do?



My code:



class NonSimilar {
private int matrix;
private List<Set<Integer>> rows = new ArrayList<>();

public NonSimilar (int matrix) {
this.matrix = matrix;
for (int i = 0; i < matrix.length; i++) {
rows.add(Arrays.stream(matrix[i]).boxed().collect(Collectors.toSet()));
}
}

public Set<int> getNonSimilarRows() {
Set<Set<Integer>> nonSimularRows = new HashSet<>();
rows.forEach(item -> nonSimularRows.add(item));
// Now I have to check successfully added rows numbers and construct new Set from Origin matrix
return new HashSet<int>();
}
}


Ok. I replaced forEach with for iteration and now all works correctly.



  public Set<int> getNonSimilarRows() {
Set<Set<Integer>> nonSimularRows = new HashSet<>();
//rows.forEach(item -> nonSimularRows.add(item));
int index = -1;
ArrayList<Integer> indexes = new ArrayList<>();
for (Set<Integer> item : rows) {
index++;
if (nonSimularRows.add(item)) {
indexes.add(index);
}
}
HashSet<int> newSet = new HashSet<int>();
for (Integer item : indexes) {
newSet.add(matrix[item]);
}
return newSet;
}


Anyway code looks very ugly and I want to get advice how I can refactor code with modern approaches like forEach and Stream API.










share|improve this question

























  • why is the expected result 1 2 2 4 4 and 3 2 4 1 5 8 but not 4 2 1 4 ?

    – Aomine
    Dec 30 '18 at 15:00






  • 1





    @Aomine I believe 1 2 2 4 4 contain the same elements as 4 2 1 4 when broken down to a set. Both would be {1, 2, 4}. I'm assuming the OP wants to the keep the first one found. Correct me If I'm wrong.

    – RoadRunner
    Dec 30 '18 at 15:02













  • Because first and second rows are similar, but first and third are not. I need to get not similar rows.

    – Dmitry Sokolov
    Dec 30 '18 at 15:03











  • Please define how the rows are similar. Is the similarity based on what RoadRunner said?

    – IPat
    Dec 30 '18 at 15:05











  • A rows is said to be similar if the sets of numbers occurring in these rows coincide

    – Dmitry Sokolov
    Dec 30 '18 at 15:12














0












0








0








I need to find non similar rows in matrix and return set of such rows.



A rows is said to be similar if the sets of numbers occurring in these rows coincide.



Example:
origin:



1 2 2 4 4
4 2 1 4
3 2 4 1 5 8


expected result:



1 2 2 4 4
3 2 4 1 5 8


My ideas:



Clean duplicates from each row via convert two dimensional array to List>



Create new set of int and add row then if row was added its means that row is non similar.then record number of row. return created new set of rows of origin matrix.
I know that I can check if element was added via Boolean return value of Add method of Set.
But there is problem by forEach, that don't provide index. And I can't use expressions inside forEach. What should I do?



My code:



class NonSimilar {
private int matrix;
private List<Set<Integer>> rows = new ArrayList<>();

public NonSimilar (int matrix) {
this.matrix = matrix;
for (int i = 0; i < matrix.length; i++) {
rows.add(Arrays.stream(matrix[i]).boxed().collect(Collectors.toSet()));
}
}

public Set<int> getNonSimilarRows() {
Set<Set<Integer>> nonSimularRows = new HashSet<>();
rows.forEach(item -> nonSimularRows.add(item));
// Now I have to check successfully added rows numbers and construct new Set from Origin matrix
return new HashSet<int>();
}
}


Ok. I replaced forEach with for iteration and now all works correctly.



  public Set<int> getNonSimilarRows() {
Set<Set<Integer>> nonSimularRows = new HashSet<>();
//rows.forEach(item -> nonSimularRows.add(item));
int index = -1;
ArrayList<Integer> indexes = new ArrayList<>();
for (Set<Integer> item : rows) {
index++;
if (nonSimularRows.add(item)) {
indexes.add(index);
}
}
HashSet<int> newSet = new HashSet<int>();
for (Integer item : indexes) {
newSet.add(matrix[item]);
}
return newSet;
}


Anyway code looks very ugly and I want to get advice how I can refactor code with modern approaches like forEach and Stream API.










share|improve this question
















I need to find non similar rows in matrix and return set of such rows.



A rows is said to be similar if the sets of numbers occurring in these rows coincide.



Example:
origin:



1 2 2 4 4
4 2 1 4
3 2 4 1 5 8


expected result:



1 2 2 4 4
3 2 4 1 5 8


My ideas:



Clean duplicates from each row via convert two dimensional array to List>



Create new set of int and add row then if row was added its means that row is non similar.then record number of row. return created new set of rows of origin matrix.
I know that I can check if element was added via Boolean return value of Add method of Set.
But there is problem by forEach, that don't provide index. And I can't use expressions inside forEach. What should I do?



My code:



class NonSimilar {
private int matrix;
private List<Set<Integer>> rows = new ArrayList<>();

public NonSimilar (int matrix) {
this.matrix = matrix;
for (int i = 0; i < matrix.length; i++) {
rows.add(Arrays.stream(matrix[i]).boxed().collect(Collectors.toSet()));
}
}

public Set<int> getNonSimilarRows() {
Set<Set<Integer>> nonSimularRows = new HashSet<>();
rows.forEach(item -> nonSimularRows.add(item));
// Now I have to check successfully added rows numbers and construct new Set from Origin matrix
return new HashSet<int>();
}
}


Ok. I replaced forEach with for iteration and now all works correctly.



  public Set<int> getNonSimilarRows() {
Set<Set<Integer>> nonSimularRows = new HashSet<>();
//rows.forEach(item -> nonSimularRows.add(item));
int index = -1;
ArrayList<Integer> indexes = new ArrayList<>();
for (Set<Integer> item : rows) {
index++;
if (nonSimularRows.add(item)) {
indexes.add(index);
}
}
HashSet<int> newSet = new HashSet<int>();
for (Integer item : indexes) {
newSet.add(matrix[item]);
}
return newSet;
}


Anyway code looks very ugly and I want to get advice how I can refactor code with modern approaches like forEach and Stream API.







java algorithm loops foreach set






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 30 '18 at 15:25







Dmitry Sokolov

















asked Dec 30 '18 at 14:50









Dmitry SokolovDmitry Sokolov

949




949













  • why is the expected result 1 2 2 4 4 and 3 2 4 1 5 8 but not 4 2 1 4 ?

    – Aomine
    Dec 30 '18 at 15:00






  • 1





    @Aomine I believe 1 2 2 4 4 contain the same elements as 4 2 1 4 when broken down to a set. Both would be {1, 2, 4}. I'm assuming the OP wants to the keep the first one found. Correct me If I'm wrong.

    – RoadRunner
    Dec 30 '18 at 15:02













  • Because first and second rows are similar, but first and third are not. I need to get not similar rows.

    – Dmitry Sokolov
    Dec 30 '18 at 15:03











  • Please define how the rows are similar. Is the similarity based on what RoadRunner said?

    – IPat
    Dec 30 '18 at 15:05











  • A rows is said to be similar if the sets of numbers occurring in these rows coincide

    – Dmitry Sokolov
    Dec 30 '18 at 15:12



















  • why is the expected result 1 2 2 4 4 and 3 2 4 1 5 8 but not 4 2 1 4 ?

    – Aomine
    Dec 30 '18 at 15:00






  • 1





    @Aomine I believe 1 2 2 4 4 contain the same elements as 4 2 1 4 when broken down to a set. Both would be {1, 2, 4}. I'm assuming the OP wants to the keep the first one found. Correct me If I'm wrong.

    – RoadRunner
    Dec 30 '18 at 15:02













  • Because first and second rows are similar, but first and third are not. I need to get not similar rows.

    – Dmitry Sokolov
    Dec 30 '18 at 15:03











  • Please define how the rows are similar. Is the similarity based on what RoadRunner said?

    – IPat
    Dec 30 '18 at 15:05











  • A rows is said to be similar if the sets of numbers occurring in these rows coincide

    – Dmitry Sokolov
    Dec 30 '18 at 15:12

















why is the expected result 1 2 2 4 4 and 3 2 4 1 5 8 but not 4 2 1 4 ?

– Aomine
Dec 30 '18 at 15:00





why is the expected result 1 2 2 4 4 and 3 2 4 1 5 8 but not 4 2 1 4 ?

– Aomine
Dec 30 '18 at 15:00




1




1





@Aomine I believe 1 2 2 4 4 contain the same elements as 4 2 1 4 when broken down to a set. Both would be {1, 2, 4}. I'm assuming the OP wants to the keep the first one found. Correct me If I'm wrong.

– RoadRunner
Dec 30 '18 at 15:02







@Aomine I believe 1 2 2 4 4 contain the same elements as 4 2 1 4 when broken down to a set. Both would be {1, 2, 4}. I'm assuming the OP wants to the keep the first one found. Correct me If I'm wrong.

– RoadRunner
Dec 30 '18 at 15:02















Because first and second rows are similar, but first and third are not. I need to get not similar rows.

– Dmitry Sokolov
Dec 30 '18 at 15:03





Because first and second rows are similar, but first and third are not. I need to get not similar rows.

– Dmitry Sokolov
Dec 30 '18 at 15:03













Please define how the rows are similar. Is the similarity based on what RoadRunner said?

– IPat
Dec 30 '18 at 15:05





Please define how the rows are similar. Is the similarity based on what RoadRunner said?

– IPat
Dec 30 '18 at 15:05













A rows is said to be similar if the sets of numbers occurring in these rows coincide

– Dmitry Sokolov
Dec 30 '18 at 15:12





A rows is said to be similar if the sets of numbers occurring in these rows coincide

– Dmitry Sokolov
Dec 30 '18 at 15:12












4 Answers
4






active

oldest

votes


















1














Let's just say that it you need to give the first non-duplicate rows of the existing matrix. Then instead of keeping the indexes in a separate list, you could use a Map for which the unique key is the set of numbers in a row and the value is the row itself. Here is the complete class with the main method to test it :



public class NonSimilar {
private final int matrix;

public NonSimilar(int matrix) {
this.matrix = matrix;
}

public Set<int> getNonSimilarRows() {
Map<Set<Integer>, int> map = new HashMap<>();
for (int row : matrix) {
map.putIfAbsent(convertRowToSet(row), row);
}
return new HashSet<>(map.values());
}

public Set<Integer> convertRowToSet(int row){
return Arrays.stream(row).boxed().collect(Collectors.toSet());
}

public static void main(String args) {
int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
Set<int> result = new NonSimilar(matrix).getNonSimilarRows();

result.forEach(row -> System.out.println(Arrays.toString(row)));
}
}


Now you might say that it prints



3 2 4 1 5 8
1 2 2 4 4


instead of



1 2 2 4 4
3 2 4 1 5 8


That's because the result is a Set and a set doesn't have the concept of order. If you really want it to be printed in the correct order, you can use a LinkedHashMap and return a LinkedHashSet.





NOTE : you can even make it shorter by using Collectors.toMap:



public Set<int> getNonSimilarRows() {
Map<Set<Integer>, int> map = Arrays.stream(matrix)
.collect(Collectors.toMap(this::convertRowToSet, Function.identity(), (r1, r2) -> null));
return new HashSet<>(map.values());
}


(r1, r2) -> r1 is to state that you accept duplicate keys and that you should keep the first value encountered. In the case of you want to keep the last value encountered, you can replace it by (r1, r2) -> r2.






share|improve this answer

































    1














    You only need 2 lines of code to remove all "similar" rows:



    Set<Set<Integer>> sets = new HashSet<>();

    List<int> nonSimilar = Arrays.stream(matrix)
    .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
    .collect(Collectors.toList());


    The add() method of Set returns true if the set was changed - ie if the element being added is not already in the set, so we can use that as a filter.



    List is chosen as the output of the stream to preserve order (a requirement that seems to be implied by the example data).



    I leave it to the reader to convert List<int> to whatever output is required, because that's unimportant to the question/answer.





    Some test code:



    int matrix = {{1, 2, 2, 4, 4},{4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
    Set<Set<Integer>> sets = new HashSet<>();

    List<int> nonSimilar = Arrays.stream(matrix)
    .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
    .collect(Collectors.toList());

    nonSimilar.stream().map(Arrays::toString).forEach(System.out::println);


    Output:



    [1, 2, 2, 4, 4]
    [3, 2, 4, 1, 5, 8]


    See live demo.






    share|improve this answer































      1














      With this




      • How to convert an Array to a Set in Java

      • How to compare two sets for equality


      you could write it like this:



      public class NonSimilarRowsTest {
      @Test
      public void test() {
      int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
      int expected = {{1, 2, 2, 4, 4}, {3, 2, 4, 1, 5, 8}};
      assertEquals(expected, nonSimilarRows(matrix));
      }

      int nonSimilarRows(int matrix) {
      Set<Set<Integer>> rows = new HashSet<>();
      int result = new int[matrix.length];
      int length = 0;

      for (int row : matrix) {
      if (rows.add(toSet(row))) {
      result[length++] = row;
      }
      }

      return Arrays.copyOf(result, length);
      }

      Set<Integer> toSet(int array) {
      return Arrays.stream(array).boxed().collect(Collectors.toSet());
      }
      }





      share|improve this answer


























      • How could you know the length of the expected result in advance?

        – Ricola
        Dec 31 '18 at 9:49











      • That's an assumption. It is a unit test and it will fail if something unexpected happens.

        – G. Fiedler
        Dec 31 '18 at 9:53











      • Yeah but you could your method return result then?

        – Ricola
        Dec 31 '18 at 10:26











      • I edited my answer: extract a function nonSimilarRows.

        – G. Fiedler
        Dec 31 '18 at 11:55



















      0














      Here's another solution that maintains an unordered set that keeps tracks of duplicate rows and also maintains order by storing the results in list:



      import java.util.Set;
      import java.util.HashSet;
      import java.util.List;
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.stream.Collectors;

      public class Test {

      private static final int rows = new int {
      { 1, 2, 2, 4, 4 },
      { 4, 2, 1, 4 },
      { 3, 2, 4, 1, 5, 8 }
      };

      private static Set<Set<Integer>> seenRows = new HashSet<>();
      private static List<int> uniqueRows = new ArrayList<>();

      public static void main(String args) {
      for (int row : rows) {
      Set<Integer> uniqueNumbers = Arrays.stream(row).boxed().collect(Collectors.toSet());
      if (!seenRows.contains(uniqueNumbers)) {
      uniqueRows.add(row);
      seenRows.add(uniqueNumbers);
      }
      }

      for (int row : uniqueRows) {
      System.out.println(Arrays.toString(row));
      }
      }
      }


      Output:



      [1, 2, 2, 4, 4]
      [3, 2, 4, 1, 5, 8]





      share|improve this answer

























        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53978605%2fjava-how-can-i-check-if-element-was-successfully-added-in-set-and-tracking-inde%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        1














        Let's just say that it you need to give the first non-duplicate rows of the existing matrix. Then instead of keeping the indexes in a separate list, you could use a Map for which the unique key is the set of numbers in a row and the value is the row itself. Here is the complete class with the main method to test it :



        public class NonSimilar {
        private final int matrix;

        public NonSimilar(int matrix) {
        this.matrix = matrix;
        }

        public Set<int> getNonSimilarRows() {
        Map<Set<Integer>, int> map = new HashMap<>();
        for (int row : matrix) {
        map.putIfAbsent(convertRowToSet(row), row);
        }
        return new HashSet<>(map.values());
        }

        public Set<Integer> convertRowToSet(int row){
        return Arrays.stream(row).boxed().collect(Collectors.toSet());
        }

        public static void main(String args) {
        int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
        Set<int> result = new NonSimilar(matrix).getNonSimilarRows();

        result.forEach(row -> System.out.println(Arrays.toString(row)));
        }
        }


        Now you might say that it prints



        3 2 4 1 5 8
        1 2 2 4 4


        instead of



        1 2 2 4 4
        3 2 4 1 5 8


        That's because the result is a Set and a set doesn't have the concept of order. If you really want it to be printed in the correct order, you can use a LinkedHashMap and return a LinkedHashSet.





        NOTE : you can even make it shorter by using Collectors.toMap:



        public Set<int> getNonSimilarRows() {
        Map<Set<Integer>, int> map = Arrays.stream(matrix)
        .collect(Collectors.toMap(this::convertRowToSet, Function.identity(), (r1, r2) -> null));
        return new HashSet<>(map.values());
        }


        (r1, r2) -> r1 is to state that you accept duplicate keys and that you should keep the first value encountered. In the case of you want to keep the last value encountered, you can replace it by (r1, r2) -> r2.






        share|improve this answer






























          1














          Let's just say that it you need to give the first non-duplicate rows of the existing matrix. Then instead of keeping the indexes in a separate list, you could use a Map for which the unique key is the set of numbers in a row and the value is the row itself. Here is the complete class with the main method to test it :



          public class NonSimilar {
          private final int matrix;

          public NonSimilar(int matrix) {
          this.matrix = matrix;
          }

          public Set<int> getNonSimilarRows() {
          Map<Set<Integer>, int> map = new HashMap<>();
          for (int row : matrix) {
          map.putIfAbsent(convertRowToSet(row), row);
          }
          return new HashSet<>(map.values());
          }

          public Set<Integer> convertRowToSet(int row){
          return Arrays.stream(row).boxed().collect(Collectors.toSet());
          }

          public static void main(String args) {
          int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
          Set<int> result = new NonSimilar(matrix).getNonSimilarRows();

          result.forEach(row -> System.out.println(Arrays.toString(row)));
          }
          }


          Now you might say that it prints



          3 2 4 1 5 8
          1 2 2 4 4


          instead of



          1 2 2 4 4
          3 2 4 1 5 8


          That's because the result is a Set and a set doesn't have the concept of order. If you really want it to be printed in the correct order, you can use a LinkedHashMap and return a LinkedHashSet.





          NOTE : you can even make it shorter by using Collectors.toMap:



          public Set<int> getNonSimilarRows() {
          Map<Set<Integer>, int> map = Arrays.stream(matrix)
          .collect(Collectors.toMap(this::convertRowToSet, Function.identity(), (r1, r2) -> null));
          return new HashSet<>(map.values());
          }


          (r1, r2) -> r1 is to state that you accept duplicate keys and that you should keep the first value encountered. In the case of you want to keep the last value encountered, you can replace it by (r1, r2) -> r2.






          share|improve this answer




























            1












            1








            1







            Let's just say that it you need to give the first non-duplicate rows of the existing matrix. Then instead of keeping the indexes in a separate list, you could use a Map for which the unique key is the set of numbers in a row and the value is the row itself. Here is the complete class with the main method to test it :



            public class NonSimilar {
            private final int matrix;

            public NonSimilar(int matrix) {
            this.matrix = matrix;
            }

            public Set<int> getNonSimilarRows() {
            Map<Set<Integer>, int> map = new HashMap<>();
            for (int row : matrix) {
            map.putIfAbsent(convertRowToSet(row), row);
            }
            return new HashSet<>(map.values());
            }

            public Set<Integer> convertRowToSet(int row){
            return Arrays.stream(row).boxed().collect(Collectors.toSet());
            }

            public static void main(String args) {
            int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
            Set<int> result = new NonSimilar(matrix).getNonSimilarRows();

            result.forEach(row -> System.out.println(Arrays.toString(row)));
            }
            }


            Now you might say that it prints



            3 2 4 1 5 8
            1 2 2 4 4


            instead of



            1 2 2 4 4
            3 2 4 1 5 8


            That's because the result is a Set and a set doesn't have the concept of order. If you really want it to be printed in the correct order, you can use a LinkedHashMap and return a LinkedHashSet.





            NOTE : you can even make it shorter by using Collectors.toMap:



            public Set<int> getNonSimilarRows() {
            Map<Set<Integer>, int> map = Arrays.stream(matrix)
            .collect(Collectors.toMap(this::convertRowToSet, Function.identity(), (r1, r2) -> null));
            return new HashSet<>(map.values());
            }


            (r1, r2) -> r1 is to state that you accept duplicate keys and that you should keep the first value encountered. In the case of you want to keep the last value encountered, you can replace it by (r1, r2) -> r2.






            share|improve this answer















            Let's just say that it you need to give the first non-duplicate rows of the existing matrix. Then instead of keeping the indexes in a separate list, you could use a Map for which the unique key is the set of numbers in a row and the value is the row itself. Here is the complete class with the main method to test it :



            public class NonSimilar {
            private final int matrix;

            public NonSimilar(int matrix) {
            this.matrix = matrix;
            }

            public Set<int> getNonSimilarRows() {
            Map<Set<Integer>, int> map = new HashMap<>();
            for (int row : matrix) {
            map.putIfAbsent(convertRowToSet(row), row);
            }
            return new HashSet<>(map.values());
            }

            public Set<Integer> convertRowToSet(int row){
            return Arrays.stream(row).boxed().collect(Collectors.toSet());
            }

            public static void main(String args) {
            int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
            Set<int> result = new NonSimilar(matrix).getNonSimilarRows();

            result.forEach(row -> System.out.println(Arrays.toString(row)));
            }
            }


            Now you might say that it prints



            3 2 4 1 5 8
            1 2 2 4 4


            instead of



            1 2 2 4 4
            3 2 4 1 5 8


            That's because the result is a Set and a set doesn't have the concept of order. If you really want it to be printed in the correct order, you can use a LinkedHashMap and return a LinkedHashSet.





            NOTE : you can even make it shorter by using Collectors.toMap:



            public Set<int> getNonSimilarRows() {
            Map<Set<Integer>, int> map = Arrays.stream(matrix)
            .collect(Collectors.toMap(this::convertRowToSet, Function.identity(), (r1, r2) -> null));
            return new HashSet<>(map.values());
            }


            (r1, r2) -> r1 is to state that you accept duplicate keys and that you should keep the first value encountered. In the case of you want to keep the last value encountered, you can replace it by (r1, r2) -> r2.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Dec 30 '18 at 20:33

























            answered Dec 30 '18 at 15:41









            RicolaRicola

            1,325314




            1,325314

























                1














                You only need 2 lines of code to remove all "similar" rows:



                Set<Set<Integer>> sets = new HashSet<>();

                List<int> nonSimilar = Arrays.stream(matrix)
                .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
                .collect(Collectors.toList());


                The add() method of Set returns true if the set was changed - ie if the element being added is not already in the set, so we can use that as a filter.



                List is chosen as the output of the stream to preserve order (a requirement that seems to be implied by the example data).



                I leave it to the reader to convert List<int> to whatever output is required, because that's unimportant to the question/answer.





                Some test code:



                int matrix = {{1, 2, 2, 4, 4},{4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
                Set<Set<Integer>> sets = new HashSet<>();

                List<int> nonSimilar = Arrays.stream(matrix)
                .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
                .collect(Collectors.toList());

                nonSimilar.stream().map(Arrays::toString).forEach(System.out::println);


                Output:



                [1, 2, 2, 4, 4]
                [3, 2, 4, 1, 5, 8]


                See live demo.






                share|improve this answer




























                  1














                  You only need 2 lines of code to remove all "similar" rows:



                  Set<Set<Integer>> sets = new HashSet<>();

                  List<int> nonSimilar = Arrays.stream(matrix)
                  .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
                  .collect(Collectors.toList());


                  The add() method of Set returns true if the set was changed - ie if the element being added is not already in the set, so we can use that as a filter.



                  List is chosen as the output of the stream to preserve order (a requirement that seems to be implied by the example data).



                  I leave it to the reader to convert List<int> to whatever output is required, because that's unimportant to the question/answer.





                  Some test code:



                  int matrix = {{1, 2, 2, 4, 4},{4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
                  Set<Set<Integer>> sets = new HashSet<>();

                  List<int> nonSimilar = Arrays.stream(matrix)
                  .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
                  .collect(Collectors.toList());

                  nonSimilar.stream().map(Arrays::toString).forEach(System.out::println);


                  Output:



                  [1, 2, 2, 4, 4]
                  [3, 2, 4, 1, 5, 8]


                  See live demo.






                  share|improve this answer


























                    1












                    1








                    1







                    You only need 2 lines of code to remove all "similar" rows:



                    Set<Set<Integer>> sets = new HashSet<>();

                    List<int> nonSimilar = Arrays.stream(matrix)
                    .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
                    .collect(Collectors.toList());


                    The add() method of Set returns true if the set was changed - ie if the element being added is not already in the set, so we can use that as a filter.



                    List is chosen as the output of the stream to preserve order (a requirement that seems to be implied by the example data).



                    I leave it to the reader to convert List<int> to whatever output is required, because that's unimportant to the question/answer.





                    Some test code:



                    int matrix = {{1, 2, 2, 4, 4},{4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
                    Set<Set<Integer>> sets = new HashSet<>();

                    List<int> nonSimilar = Arrays.stream(matrix)
                    .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
                    .collect(Collectors.toList());

                    nonSimilar.stream().map(Arrays::toString).forEach(System.out::println);


                    Output:



                    [1, 2, 2, 4, 4]
                    [3, 2, 4, 1, 5, 8]


                    See live demo.






                    share|improve this answer













                    You only need 2 lines of code to remove all "similar" rows:



                    Set<Set<Integer>> sets = new HashSet<>();

                    List<int> nonSimilar = Arrays.stream(matrix)
                    .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
                    .collect(Collectors.toList());


                    The add() method of Set returns true if the set was changed - ie if the element being added is not already in the set, so we can use that as a filter.



                    List is chosen as the output of the stream to preserve order (a requirement that seems to be implied by the example data).



                    I leave it to the reader to convert List<int> to whatever output is required, because that's unimportant to the question/answer.





                    Some test code:



                    int matrix = {{1, 2, 2, 4, 4},{4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
                    Set<Set<Integer>> sets = new HashSet<>();

                    List<int> nonSimilar = Arrays.stream(matrix)
                    .filter(row -> sets.add(Arrays.stream(row).boxed().collect(Collectors.toSet())))
                    .collect(Collectors.toList());

                    nonSimilar.stream().map(Arrays::toString).forEach(System.out::println);


                    Output:



                    [1, 2, 2, 4, 4]
                    [3, 2, 4, 1, 5, 8]


                    See live demo.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Dec 30 '18 at 21:50









                    BohemianBohemian

                    296k64420555




                    296k64420555























                        1














                        With this




                        • How to convert an Array to a Set in Java

                        • How to compare two sets for equality


                        you could write it like this:



                        public class NonSimilarRowsTest {
                        @Test
                        public void test() {
                        int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
                        int expected = {{1, 2, 2, 4, 4}, {3, 2, 4, 1, 5, 8}};
                        assertEquals(expected, nonSimilarRows(matrix));
                        }

                        int nonSimilarRows(int matrix) {
                        Set<Set<Integer>> rows = new HashSet<>();
                        int result = new int[matrix.length];
                        int length = 0;

                        for (int row : matrix) {
                        if (rows.add(toSet(row))) {
                        result[length++] = row;
                        }
                        }

                        return Arrays.copyOf(result, length);
                        }

                        Set<Integer> toSet(int array) {
                        return Arrays.stream(array).boxed().collect(Collectors.toSet());
                        }
                        }





                        share|improve this answer


























                        • How could you know the length of the expected result in advance?

                          – Ricola
                          Dec 31 '18 at 9:49











                        • That's an assumption. It is a unit test and it will fail if something unexpected happens.

                          – G. Fiedler
                          Dec 31 '18 at 9:53











                        • Yeah but you could your method return result then?

                          – Ricola
                          Dec 31 '18 at 10:26











                        • I edited my answer: extract a function nonSimilarRows.

                          – G. Fiedler
                          Dec 31 '18 at 11:55
















                        1














                        With this




                        • How to convert an Array to a Set in Java

                        • How to compare two sets for equality


                        you could write it like this:



                        public class NonSimilarRowsTest {
                        @Test
                        public void test() {
                        int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
                        int expected = {{1, 2, 2, 4, 4}, {3, 2, 4, 1, 5, 8}};
                        assertEquals(expected, nonSimilarRows(matrix));
                        }

                        int nonSimilarRows(int matrix) {
                        Set<Set<Integer>> rows = new HashSet<>();
                        int result = new int[matrix.length];
                        int length = 0;

                        for (int row : matrix) {
                        if (rows.add(toSet(row))) {
                        result[length++] = row;
                        }
                        }

                        return Arrays.copyOf(result, length);
                        }

                        Set<Integer> toSet(int array) {
                        return Arrays.stream(array).boxed().collect(Collectors.toSet());
                        }
                        }





                        share|improve this answer


























                        • How could you know the length of the expected result in advance?

                          – Ricola
                          Dec 31 '18 at 9:49











                        • That's an assumption. It is a unit test and it will fail if something unexpected happens.

                          – G. Fiedler
                          Dec 31 '18 at 9:53











                        • Yeah but you could your method return result then?

                          – Ricola
                          Dec 31 '18 at 10:26











                        • I edited my answer: extract a function nonSimilarRows.

                          – G. Fiedler
                          Dec 31 '18 at 11:55














                        1












                        1








                        1







                        With this




                        • How to convert an Array to a Set in Java

                        • How to compare two sets for equality


                        you could write it like this:



                        public class NonSimilarRowsTest {
                        @Test
                        public void test() {
                        int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
                        int expected = {{1, 2, 2, 4, 4}, {3, 2, 4, 1, 5, 8}};
                        assertEquals(expected, nonSimilarRows(matrix));
                        }

                        int nonSimilarRows(int matrix) {
                        Set<Set<Integer>> rows = new HashSet<>();
                        int result = new int[matrix.length];
                        int length = 0;

                        for (int row : matrix) {
                        if (rows.add(toSet(row))) {
                        result[length++] = row;
                        }
                        }

                        return Arrays.copyOf(result, length);
                        }

                        Set<Integer> toSet(int array) {
                        return Arrays.stream(array).boxed().collect(Collectors.toSet());
                        }
                        }





                        share|improve this answer















                        With this




                        • How to convert an Array to a Set in Java

                        • How to compare two sets for equality


                        you could write it like this:



                        public class NonSimilarRowsTest {
                        @Test
                        public void test() {
                        int matrix = {{1, 2, 2, 4, 4}, {4, 2, 1, 4}, {3, 2, 4, 1, 5, 8}};
                        int expected = {{1, 2, 2, 4, 4}, {3, 2, 4, 1, 5, 8}};
                        assertEquals(expected, nonSimilarRows(matrix));
                        }

                        int nonSimilarRows(int matrix) {
                        Set<Set<Integer>> rows = new HashSet<>();
                        int result = new int[matrix.length];
                        int length = 0;

                        for (int row : matrix) {
                        if (rows.add(toSet(row))) {
                        result[length++] = row;
                        }
                        }

                        return Arrays.copyOf(result, length);
                        }

                        Set<Integer> toSet(int array) {
                        return Arrays.stream(array).boxed().collect(Collectors.toSet());
                        }
                        }






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Dec 31 '18 at 11:54

























                        answered Dec 30 '18 at 21:24









                        G. FiedlerG. Fiedler

                        42919




                        42919













                        • How could you know the length of the expected result in advance?

                          – Ricola
                          Dec 31 '18 at 9:49











                        • That's an assumption. It is a unit test and it will fail if something unexpected happens.

                          – G. Fiedler
                          Dec 31 '18 at 9:53











                        • Yeah but you could your method return result then?

                          – Ricola
                          Dec 31 '18 at 10:26











                        • I edited my answer: extract a function nonSimilarRows.

                          – G. Fiedler
                          Dec 31 '18 at 11:55



















                        • How could you know the length of the expected result in advance?

                          – Ricola
                          Dec 31 '18 at 9:49











                        • That's an assumption. It is a unit test and it will fail if something unexpected happens.

                          – G. Fiedler
                          Dec 31 '18 at 9:53











                        • Yeah but you could your method return result then?

                          – Ricola
                          Dec 31 '18 at 10:26











                        • I edited my answer: extract a function nonSimilarRows.

                          – G. Fiedler
                          Dec 31 '18 at 11:55

















                        How could you know the length of the expected result in advance?

                        – Ricola
                        Dec 31 '18 at 9:49





                        How could you know the length of the expected result in advance?

                        – Ricola
                        Dec 31 '18 at 9:49













                        That's an assumption. It is a unit test and it will fail if something unexpected happens.

                        – G. Fiedler
                        Dec 31 '18 at 9:53





                        That's an assumption. It is a unit test and it will fail if something unexpected happens.

                        – G. Fiedler
                        Dec 31 '18 at 9:53













                        Yeah but you could your method return result then?

                        – Ricola
                        Dec 31 '18 at 10:26





                        Yeah but you could your method return result then?

                        – Ricola
                        Dec 31 '18 at 10:26













                        I edited my answer: extract a function nonSimilarRows.

                        – G. Fiedler
                        Dec 31 '18 at 11:55





                        I edited my answer: extract a function nonSimilarRows.

                        – G. Fiedler
                        Dec 31 '18 at 11:55











                        0














                        Here's another solution that maintains an unordered set that keeps tracks of duplicate rows and also maintains order by storing the results in list:



                        import java.util.Set;
                        import java.util.HashSet;
                        import java.util.List;
                        import java.util.ArrayList;
                        import java.util.Arrays;
                        import java.util.stream.Collectors;

                        public class Test {

                        private static final int rows = new int {
                        { 1, 2, 2, 4, 4 },
                        { 4, 2, 1, 4 },
                        { 3, 2, 4, 1, 5, 8 }
                        };

                        private static Set<Set<Integer>> seenRows = new HashSet<>();
                        private static List<int> uniqueRows = new ArrayList<>();

                        public static void main(String args) {
                        for (int row : rows) {
                        Set<Integer> uniqueNumbers = Arrays.stream(row).boxed().collect(Collectors.toSet());
                        if (!seenRows.contains(uniqueNumbers)) {
                        uniqueRows.add(row);
                        seenRows.add(uniqueNumbers);
                        }
                        }

                        for (int row : uniqueRows) {
                        System.out.println(Arrays.toString(row));
                        }
                        }
                        }


                        Output:



                        [1, 2, 2, 4, 4]
                        [3, 2, 4, 1, 5, 8]





                        share|improve this answer






























                          0














                          Here's another solution that maintains an unordered set that keeps tracks of duplicate rows and also maintains order by storing the results in list:



                          import java.util.Set;
                          import java.util.HashSet;
                          import java.util.List;
                          import java.util.ArrayList;
                          import java.util.Arrays;
                          import java.util.stream.Collectors;

                          public class Test {

                          private static final int rows = new int {
                          { 1, 2, 2, 4, 4 },
                          { 4, 2, 1, 4 },
                          { 3, 2, 4, 1, 5, 8 }
                          };

                          private static Set<Set<Integer>> seenRows = new HashSet<>();
                          private static List<int> uniqueRows = new ArrayList<>();

                          public static void main(String args) {
                          for (int row : rows) {
                          Set<Integer> uniqueNumbers = Arrays.stream(row).boxed().collect(Collectors.toSet());
                          if (!seenRows.contains(uniqueNumbers)) {
                          uniqueRows.add(row);
                          seenRows.add(uniqueNumbers);
                          }
                          }

                          for (int row : uniqueRows) {
                          System.out.println(Arrays.toString(row));
                          }
                          }
                          }


                          Output:



                          [1, 2, 2, 4, 4]
                          [3, 2, 4, 1, 5, 8]





                          share|improve this answer




























                            0












                            0








                            0







                            Here's another solution that maintains an unordered set that keeps tracks of duplicate rows and also maintains order by storing the results in list:



                            import java.util.Set;
                            import java.util.HashSet;
                            import java.util.List;
                            import java.util.ArrayList;
                            import java.util.Arrays;
                            import java.util.stream.Collectors;

                            public class Test {

                            private static final int rows = new int {
                            { 1, 2, 2, 4, 4 },
                            { 4, 2, 1, 4 },
                            { 3, 2, 4, 1, 5, 8 }
                            };

                            private static Set<Set<Integer>> seenRows = new HashSet<>();
                            private static List<int> uniqueRows = new ArrayList<>();

                            public static void main(String args) {
                            for (int row : rows) {
                            Set<Integer> uniqueNumbers = Arrays.stream(row).boxed().collect(Collectors.toSet());
                            if (!seenRows.contains(uniqueNumbers)) {
                            uniqueRows.add(row);
                            seenRows.add(uniqueNumbers);
                            }
                            }

                            for (int row : uniqueRows) {
                            System.out.println(Arrays.toString(row));
                            }
                            }
                            }


                            Output:



                            [1, 2, 2, 4, 4]
                            [3, 2, 4, 1, 5, 8]





                            share|improve this answer















                            Here's another solution that maintains an unordered set that keeps tracks of duplicate rows and also maintains order by storing the results in list:



                            import java.util.Set;
                            import java.util.HashSet;
                            import java.util.List;
                            import java.util.ArrayList;
                            import java.util.Arrays;
                            import java.util.stream.Collectors;

                            public class Test {

                            private static final int rows = new int {
                            { 1, 2, 2, 4, 4 },
                            { 4, 2, 1, 4 },
                            { 3, 2, 4, 1, 5, 8 }
                            };

                            private static Set<Set<Integer>> seenRows = new HashSet<>();
                            private static List<int> uniqueRows = new ArrayList<>();

                            public static void main(String args) {
                            for (int row : rows) {
                            Set<Integer> uniqueNumbers = Arrays.stream(row).boxed().collect(Collectors.toSet());
                            if (!seenRows.contains(uniqueNumbers)) {
                            uniqueRows.add(row);
                            seenRows.add(uniqueNumbers);
                            }
                            }

                            for (int row : uniqueRows) {
                            System.out.println(Arrays.toString(row));
                            }
                            }
                            }


                            Output:



                            [1, 2, 2, 4, 4]
                            [3, 2, 4, 1, 5, 8]






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Dec 31 '18 at 3:54

























                            answered Dec 31 '18 at 3:41









                            RoadRunnerRoadRunner

                            11.2k31340




                            11.2k31340






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53978605%2fjava-how-can-i-check-if-element-was-successfully-added-in-set-and-tracking-inde%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Monofisismo

                                Angular Downloading a file using contenturl with Basic Authentication

                                Olmecas