Find only repeated String attributes in list with Java 8











up vote
7
down vote

favorite












I know below is the code to find out the occurrence of each String attributes in list , how can I filter this list with only duplicates item i.e having more than 1 occurrence. Sorry I am new to java 8 .



Map<String, Long> result = list.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));









share|improve this question









New contributor




Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • I like this way: How to check if exists any duplicate in Java 8 Streams?
    – Juan Sebastian Ocampo Ospina
    6 hours ago















up vote
7
down vote

favorite












I know below is the code to find out the occurrence of each String attributes in list , how can I filter this list with only duplicates item i.e having more than 1 occurrence. Sorry I am new to java 8 .



Map<String, Long> result = list.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));









share|improve this question









New contributor




Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • I like this way: How to check if exists any duplicate in Java 8 Streams?
    – Juan Sebastian Ocampo Ospina
    6 hours ago













up vote
7
down vote

favorite









up vote
7
down vote

favorite











I know below is the code to find out the occurrence of each String attributes in list , how can I filter this list with only duplicates item i.e having more than 1 occurrence. Sorry I am new to java 8 .



Map<String, Long> result = list.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));









share|improve this question









New contributor




Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I know below is the code to find out the occurrence of each String attributes in list , how can I filter this list with only duplicates item i.e having more than 1 occurrence. Sorry I am new to java 8 .



Map<String, Long> result = list.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));






java java-8 java-stream






share|improve this question









New contributor




Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 6 hours ago









Aomine

33.2k62755




33.2k62755






New contributor




Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 6 hours ago









Rishabh Chaturvedi

362




362




New contributor




Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Rishabh Chaturvedi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • I like this way: How to check if exists any duplicate in Java 8 Streams?
    – Juan Sebastian Ocampo Ospina
    6 hours ago


















  • I like this way: How to check if exists any duplicate in Java 8 Streams?
    – Juan Sebastian Ocampo Ospina
    6 hours ago
















I like this way: How to check if exists any duplicate in Java 8 Streams?
– Juan Sebastian Ocampo Ospina
6 hours ago




I like this way: How to check if exists any duplicate in Java 8 Streams?
– Juan Sebastian Ocampo Ospina
6 hours ago












4 Answers
4






active

oldest

votes

















up vote
5
down vote













create a stream from the entrySet and filter:



List<Map.Entry<String, Long>> result =  list.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.filter(s -> s.getValue() >= 2)
.collect(Collectors.toList());


or if you want to maintain a map then:



Map<String, Long> result = stringList().stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.filter(s -> s.getValue() >= 2)
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));


on another note, if you just want the individual numbers that have more than or equal to 2 occurrences then you can do:



List<String> result = list.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()))
.entrySet()
.stream()
.filter(x -> x.getValue() >= 2)
.map(Map.Entry::getKey)
.collect(toList());


another option being:



List<String> result = 
list.stream()
.filter(x -> list.stream().filter(x::equals).limit(2).count() == 2)
.distinct()
.collect(toList());





share|improve this answer























  • I would personally prefer filtering out based on a logic over creating stream twice.
    – nullpointer
    5 hours ago










  • @nullpointer mhmmm.. what do you mean?
    – Aomine
    5 hours ago










  • list.stream() .filter(x -> list.stream().filter.. was pointing out this.
    – nullpointer
    5 hours ago










  • @nullpointer so what do you suggest to replace that with?
    – Aomine
    5 hours ago






  • 1




    Well, at least one such solution has been added to my answer. Just a choice to avoid using stream twice.
    – nullpointer
    5 hours ago


















up vote
5
down vote













If your List is mutable, you can directly remove all elements except their second occurrence:



// example list
List<String> example = new ArrayList<>();
Collections.addAll(example, "foo", "bar", "baz", "bar", "bar", "baz");

// actual operation
Map<String,Integer> temp = new HashMap<>();
example.removeIf(s -> temp.merge(s, 1, Integer::sum)!=2);

// example output
example.forEach(System.out::println);// prints bar baz


The solution above keeps only one copy for each string having multiple occurrences while removing all strings having no duplicates. If you want to keep all duplicates and just remove those string not having duplicates, there is no way around determining the duplicate status first.



// same example input as above

// actual operation
Map<String,Boolean> temp = new HashMap<>();
example.forEach(s -> temp.merge(s, true, (a,b) -> false));
example.removeIf(temp::get);

// example output
example.forEach(System.out::println);// prints bar baz bar bar baz


Here, the temporary map can be created with a Stream operation with the same logic:



Map<String,Boolean> temp = example.stream()
.collect(Collectors.toMap(Function.identity(), s -> true, (a,b) -> false));
example.removeIf(temp::get);





share|improve this answer




























    up vote
    3
    down vote













    The other way would be like this. after groupBy then remove entry with value=1;



    result = list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    result.values().removeIf(v->v.intValue() == 1);





    share|improve this answer

















    • 1




      result.entrySet().removeIf(v -> v.getValue() == 1); Set<String> res = result.keySet(); would be better I believe.. you can remove the entry instead of removing a value specifically from a list of values.
      – nullpointer
      5 hours ago








    • 3




      @nullpointer there is no difference between result.values().removeIf(v -> == 1) and result.entrySet().removeIf(v -> v.getValue() == 1), except that the latter is more verbose. Both variants iterate over the map and remove matching entries.
      – Holger
      4 hours ago


















    up vote
    2
    down vote













    A simpler way to find that out could be



    List<String> recurringItems = list.stream()
    .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
    .collect(Collectors.toList());


    Since for items occurring more than once, lastIndex wouldn't be equal to the first index.





    Alternatively, you can use Collectors.toSet() to ensure the items are listed only once in case you are not interested in their order of recurrence.



    Set<String> recurringItemsOnce = list.stream()
    .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
    .collect(Collectors.toSet());


    Or using Collections.frequency as:



    Set<String> recurringItems = list.stream()
    .filter(item -> Collections.frequency(list, item) >= 2)
    .collect(Collectors.toSet());





    share|improve this answer























    • this would retrieve duplicate items, e.g. if our list was Arrays.asList("1","2","3","1","56","4","4") then as a result you'd have [1, 1, 4, 4] instead of [1, 4] which of course you could solve by adding a distinct call after the filter. on another note, it would be sufficient to keep it as is if the OP wants to get the occurrence of a particular number in the list which requires some additional searching... so ultimately it might be better to proceed with OP's approach.
      – Aomine
      6 hours ago












    • @Aomine Indeed, if the eventual result is desired to just have the items distinct would help. Otherwise, if the sequence in which the duplicates occur matters, this can still be used. Added both for completeness.
      – nullpointer
      6 hours ago






    • 2




      Simpler in source code, but horrible regarding performance. The OP's original approach using groupingBy as starting point is much preferable.
      – Holger
      5 hours ago










    • @Holger Can you shed some details over the horrible regarding performance part. SInce I was considering that collecting to a Map using a stream and then performing operations would still be equal in performance.
      – nullpointer
      4 hours ago






    • 2




      indexOf and lastIndexOf are linear searches. You can even predict, that for unique elements, all elements of the list will be traversed when searching once from the beginning and once from the end, and you are repeating this for every element, so the worst case of your operation will be n×n. In case of frequency, which counts all occurrences, it will always be n×n. Whereas the filling of the map will always be n operations, even if hash operation are more costly and it bears allocations, but that's a fixed constant factor, not growing with the number of elements.
      – Holger
      4 hours ago











    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',
    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
    });


    }
    });






    Rishabh Chaturvedi is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53584012%2ffind-only-repeated-string-attributes-in-list-with-java-8%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








    up vote
    5
    down vote













    create a stream from the entrySet and filter:



    List<Map.Entry<String, Long>> result =  list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(s -> s.getValue() >= 2)
    .collect(Collectors.toList());


    or if you want to maintain a map then:



    Map<String, Long> result = stringList().stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(s -> s.getValue() >= 2)
    .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));


    on another note, if you just want the individual numbers that have more than or equal to 2 occurrences then you can do:



    List<String> result = list.stream()
    .collect(Collectors.groupingBy(Function.identity(),
    Collectors.counting()))
    .entrySet()
    .stream()
    .filter(x -> x.getValue() >= 2)
    .map(Map.Entry::getKey)
    .collect(toList());


    another option being:



    List<String> result = 
    list.stream()
    .filter(x -> list.stream().filter(x::equals).limit(2).count() == 2)
    .distinct()
    .collect(toList());





    share|improve this answer























    • I would personally prefer filtering out based on a logic over creating stream twice.
      – nullpointer
      5 hours ago










    • @nullpointer mhmmm.. what do you mean?
      – Aomine
      5 hours ago










    • list.stream() .filter(x -> list.stream().filter.. was pointing out this.
      – nullpointer
      5 hours ago










    • @nullpointer so what do you suggest to replace that with?
      – Aomine
      5 hours ago






    • 1




      Well, at least one such solution has been added to my answer. Just a choice to avoid using stream twice.
      – nullpointer
      5 hours ago















    up vote
    5
    down vote













    create a stream from the entrySet and filter:



    List<Map.Entry<String, Long>> result =  list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(s -> s.getValue() >= 2)
    .collect(Collectors.toList());


    or if you want to maintain a map then:



    Map<String, Long> result = stringList().stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(s -> s.getValue() >= 2)
    .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));


    on another note, if you just want the individual numbers that have more than or equal to 2 occurrences then you can do:



    List<String> result = list.stream()
    .collect(Collectors.groupingBy(Function.identity(),
    Collectors.counting()))
    .entrySet()
    .stream()
    .filter(x -> x.getValue() >= 2)
    .map(Map.Entry::getKey)
    .collect(toList());


    another option being:



    List<String> result = 
    list.stream()
    .filter(x -> list.stream().filter(x::equals).limit(2).count() == 2)
    .distinct()
    .collect(toList());





    share|improve this answer























    • I would personally prefer filtering out based on a logic over creating stream twice.
      – nullpointer
      5 hours ago










    • @nullpointer mhmmm.. what do you mean?
      – Aomine
      5 hours ago










    • list.stream() .filter(x -> list.stream().filter.. was pointing out this.
      – nullpointer
      5 hours ago










    • @nullpointer so what do you suggest to replace that with?
      – Aomine
      5 hours ago






    • 1




      Well, at least one such solution has been added to my answer. Just a choice to avoid using stream twice.
      – nullpointer
      5 hours ago













    up vote
    5
    down vote










    up vote
    5
    down vote









    create a stream from the entrySet and filter:



    List<Map.Entry<String, Long>> result =  list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(s -> s.getValue() >= 2)
    .collect(Collectors.toList());


    or if you want to maintain a map then:



    Map<String, Long> result = stringList().stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(s -> s.getValue() >= 2)
    .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));


    on another note, if you just want the individual numbers that have more than or equal to 2 occurrences then you can do:



    List<String> result = list.stream()
    .collect(Collectors.groupingBy(Function.identity(),
    Collectors.counting()))
    .entrySet()
    .stream()
    .filter(x -> x.getValue() >= 2)
    .map(Map.Entry::getKey)
    .collect(toList());


    another option being:



    List<String> result = 
    list.stream()
    .filter(x -> list.stream().filter(x::equals).limit(2).count() == 2)
    .distinct()
    .collect(toList());





    share|improve this answer














    create a stream from the entrySet and filter:



    List<Map.Entry<String, Long>> result =  list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(s -> s.getValue() >= 2)
    .collect(Collectors.toList());


    or if you want to maintain a map then:



    Map<String, Long> result = stringList().stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(s -> s.getValue() >= 2)
    .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));


    on another note, if you just want the individual numbers that have more than or equal to 2 occurrences then you can do:



    List<String> result = list.stream()
    .collect(Collectors.groupingBy(Function.identity(),
    Collectors.counting()))
    .entrySet()
    .stream()
    .filter(x -> x.getValue() >= 2)
    .map(Map.Entry::getKey)
    .collect(toList());


    another option being:



    List<String> result = 
    list.stream()
    .filter(x -> list.stream().filter(x::equals).limit(2).count() == 2)
    .distinct()
    .collect(toList());






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 5 hours ago

























    answered 6 hours ago









    Aomine

    33.2k62755




    33.2k62755












    • I would personally prefer filtering out based on a logic over creating stream twice.
      – nullpointer
      5 hours ago










    • @nullpointer mhmmm.. what do you mean?
      – Aomine
      5 hours ago










    • list.stream() .filter(x -> list.stream().filter.. was pointing out this.
      – nullpointer
      5 hours ago










    • @nullpointer so what do you suggest to replace that with?
      – Aomine
      5 hours ago






    • 1




      Well, at least one such solution has been added to my answer. Just a choice to avoid using stream twice.
      – nullpointer
      5 hours ago


















    • I would personally prefer filtering out based on a logic over creating stream twice.
      – nullpointer
      5 hours ago










    • @nullpointer mhmmm.. what do you mean?
      – Aomine
      5 hours ago










    • list.stream() .filter(x -> list.stream().filter.. was pointing out this.
      – nullpointer
      5 hours ago










    • @nullpointer so what do you suggest to replace that with?
      – Aomine
      5 hours ago






    • 1




      Well, at least one such solution has been added to my answer. Just a choice to avoid using stream twice.
      – nullpointer
      5 hours ago
















    I would personally prefer filtering out based on a logic over creating stream twice.
    – nullpointer
    5 hours ago




    I would personally prefer filtering out based on a logic over creating stream twice.
    – nullpointer
    5 hours ago












    @nullpointer mhmmm.. what do you mean?
    – Aomine
    5 hours ago




    @nullpointer mhmmm.. what do you mean?
    – Aomine
    5 hours ago












    list.stream() .filter(x -> list.stream().filter.. was pointing out this.
    – nullpointer
    5 hours ago




    list.stream() .filter(x -> list.stream().filter.. was pointing out this.
    – nullpointer
    5 hours ago












    @nullpointer so what do you suggest to replace that with?
    – Aomine
    5 hours ago




    @nullpointer so what do you suggest to replace that with?
    – Aomine
    5 hours ago




    1




    1




    Well, at least one such solution has been added to my answer. Just a choice to avoid using stream twice.
    – nullpointer
    5 hours ago




    Well, at least one such solution has been added to my answer. Just a choice to avoid using stream twice.
    – nullpointer
    5 hours ago












    up vote
    5
    down vote













    If your List is mutable, you can directly remove all elements except their second occurrence:



    // example list
    List<String> example = new ArrayList<>();
    Collections.addAll(example, "foo", "bar", "baz", "bar", "bar", "baz");

    // actual operation
    Map<String,Integer> temp = new HashMap<>();
    example.removeIf(s -> temp.merge(s, 1, Integer::sum)!=2);

    // example output
    example.forEach(System.out::println);// prints bar baz


    The solution above keeps only one copy for each string having multiple occurrences while removing all strings having no duplicates. If you want to keep all duplicates and just remove those string not having duplicates, there is no way around determining the duplicate status first.



    // same example input as above

    // actual operation
    Map<String,Boolean> temp = new HashMap<>();
    example.forEach(s -> temp.merge(s, true, (a,b) -> false));
    example.removeIf(temp::get);

    // example output
    example.forEach(System.out::println);// prints bar baz bar bar baz


    Here, the temporary map can be created with a Stream operation with the same logic:



    Map<String,Boolean> temp = example.stream()
    .collect(Collectors.toMap(Function.identity(), s -> true, (a,b) -> false));
    example.removeIf(temp::get);





    share|improve this answer

























      up vote
      5
      down vote













      If your List is mutable, you can directly remove all elements except their second occurrence:



      // example list
      List<String> example = new ArrayList<>();
      Collections.addAll(example, "foo", "bar", "baz", "bar", "bar", "baz");

      // actual operation
      Map<String,Integer> temp = new HashMap<>();
      example.removeIf(s -> temp.merge(s, 1, Integer::sum)!=2);

      // example output
      example.forEach(System.out::println);// prints bar baz


      The solution above keeps only one copy for each string having multiple occurrences while removing all strings having no duplicates. If you want to keep all duplicates and just remove those string not having duplicates, there is no way around determining the duplicate status first.



      // same example input as above

      // actual operation
      Map<String,Boolean> temp = new HashMap<>();
      example.forEach(s -> temp.merge(s, true, (a,b) -> false));
      example.removeIf(temp::get);

      // example output
      example.forEach(System.out::println);// prints bar baz bar bar baz


      Here, the temporary map can be created with a Stream operation with the same logic:



      Map<String,Boolean> temp = example.stream()
      .collect(Collectors.toMap(Function.identity(), s -> true, (a,b) -> false));
      example.removeIf(temp::get);





      share|improve this answer























        up vote
        5
        down vote










        up vote
        5
        down vote









        If your List is mutable, you can directly remove all elements except their second occurrence:



        // example list
        List<String> example = new ArrayList<>();
        Collections.addAll(example, "foo", "bar", "baz", "bar", "bar", "baz");

        // actual operation
        Map<String,Integer> temp = new HashMap<>();
        example.removeIf(s -> temp.merge(s, 1, Integer::sum)!=2);

        // example output
        example.forEach(System.out::println);// prints bar baz


        The solution above keeps only one copy for each string having multiple occurrences while removing all strings having no duplicates. If you want to keep all duplicates and just remove those string not having duplicates, there is no way around determining the duplicate status first.



        // same example input as above

        // actual operation
        Map<String,Boolean> temp = new HashMap<>();
        example.forEach(s -> temp.merge(s, true, (a,b) -> false));
        example.removeIf(temp::get);

        // example output
        example.forEach(System.out::println);// prints bar baz bar bar baz


        Here, the temporary map can be created with a Stream operation with the same logic:



        Map<String,Boolean> temp = example.stream()
        .collect(Collectors.toMap(Function.identity(), s -> true, (a,b) -> false));
        example.removeIf(temp::get);





        share|improve this answer












        If your List is mutable, you can directly remove all elements except their second occurrence:



        // example list
        List<String> example = new ArrayList<>();
        Collections.addAll(example, "foo", "bar", "baz", "bar", "bar", "baz");

        // actual operation
        Map<String,Integer> temp = new HashMap<>();
        example.removeIf(s -> temp.merge(s, 1, Integer::sum)!=2);

        // example output
        example.forEach(System.out::println);// prints bar baz


        The solution above keeps only one copy for each string having multiple occurrences while removing all strings having no duplicates. If you want to keep all duplicates and just remove those string not having duplicates, there is no way around determining the duplicate status first.



        // same example input as above

        // actual operation
        Map<String,Boolean> temp = new HashMap<>();
        example.forEach(s -> temp.merge(s, true, (a,b) -> false));
        example.removeIf(temp::get);

        // example output
        example.forEach(System.out::println);// prints bar baz bar bar baz


        Here, the temporary map can be created with a Stream operation with the same logic:



        Map<String,Boolean> temp = example.stream()
        .collect(Collectors.toMap(Function.identity(), s -> true, (a,b) -> false));
        example.removeIf(temp::get);






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 4 hours ago









        Holger

        159k23221424




        159k23221424






















            up vote
            3
            down vote













            The other way would be like this. after groupBy then remove entry with value=1;



            result = list.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
            result.values().removeIf(v->v.intValue() == 1);





            share|improve this answer

















            • 1




              result.entrySet().removeIf(v -> v.getValue() == 1); Set<String> res = result.keySet(); would be better I believe.. you can remove the entry instead of removing a value specifically from a list of values.
              – nullpointer
              5 hours ago








            • 3




              @nullpointer there is no difference between result.values().removeIf(v -> == 1) and result.entrySet().removeIf(v -> v.getValue() == 1), except that the latter is more verbose. Both variants iterate over the map and remove matching entries.
              – Holger
              4 hours ago















            up vote
            3
            down vote













            The other way would be like this. after groupBy then remove entry with value=1;



            result = list.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
            result.values().removeIf(v->v.intValue() == 1);





            share|improve this answer

















            • 1




              result.entrySet().removeIf(v -> v.getValue() == 1); Set<String> res = result.keySet(); would be better I believe.. you can remove the entry instead of removing a value specifically from a list of values.
              – nullpointer
              5 hours ago








            • 3




              @nullpointer there is no difference between result.values().removeIf(v -> == 1) and result.entrySet().removeIf(v -> v.getValue() == 1), except that the latter is more verbose. Both variants iterate over the map and remove matching entries.
              – Holger
              4 hours ago













            up vote
            3
            down vote










            up vote
            3
            down vote









            The other way would be like this. after groupBy then remove entry with value=1;



            result = list.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
            result.values().removeIf(v->v.intValue() == 1);





            share|improve this answer












            The other way would be like this. after groupBy then remove entry with value=1;



            result = list.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
            result.values().removeIf(v->v.intValue() == 1);






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 5 hours ago









            Hadi J

            9,40431539




            9,40431539








            • 1




              result.entrySet().removeIf(v -> v.getValue() == 1); Set<String> res = result.keySet(); would be better I believe.. you can remove the entry instead of removing a value specifically from a list of values.
              – nullpointer
              5 hours ago








            • 3




              @nullpointer there is no difference between result.values().removeIf(v -> == 1) and result.entrySet().removeIf(v -> v.getValue() == 1), except that the latter is more verbose. Both variants iterate over the map and remove matching entries.
              – Holger
              4 hours ago














            • 1




              result.entrySet().removeIf(v -> v.getValue() == 1); Set<String> res = result.keySet(); would be better I believe.. you can remove the entry instead of removing a value specifically from a list of values.
              – nullpointer
              5 hours ago








            • 3




              @nullpointer there is no difference between result.values().removeIf(v -> == 1) and result.entrySet().removeIf(v -> v.getValue() == 1), except that the latter is more verbose. Both variants iterate over the map and remove matching entries.
              – Holger
              4 hours ago








            1




            1




            result.entrySet().removeIf(v -> v.getValue() == 1); Set<String> res = result.keySet(); would be better I believe.. you can remove the entry instead of removing a value specifically from a list of values.
            – nullpointer
            5 hours ago






            result.entrySet().removeIf(v -> v.getValue() == 1); Set<String> res = result.keySet(); would be better I believe.. you can remove the entry instead of removing a value specifically from a list of values.
            – nullpointer
            5 hours ago






            3




            3




            @nullpointer there is no difference between result.values().removeIf(v -> == 1) and result.entrySet().removeIf(v -> v.getValue() == 1), except that the latter is more verbose. Both variants iterate over the map and remove matching entries.
            – Holger
            4 hours ago




            @nullpointer there is no difference between result.values().removeIf(v -> == 1) and result.entrySet().removeIf(v -> v.getValue() == 1), except that the latter is more verbose. Both variants iterate over the map and remove matching entries.
            – Holger
            4 hours ago










            up vote
            2
            down vote













            A simpler way to find that out could be



            List<String> recurringItems = list.stream()
            .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
            .collect(Collectors.toList());


            Since for items occurring more than once, lastIndex wouldn't be equal to the first index.





            Alternatively, you can use Collectors.toSet() to ensure the items are listed only once in case you are not interested in their order of recurrence.



            Set<String> recurringItemsOnce = list.stream()
            .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
            .collect(Collectors.toSet());


            Or using Collections.frequency as:



            Set<String> recurringItems = list.stream()
            .filter(item -> Collections.frequency(list, item) >= 2)
            .collect(Collectors.toSet());





            share|improve this answer























            • this would retrieve duplicate items, e.g. if our list was Arrays.asList("1","2","3","1","56","4","4") then as a result you'd have [1, 1, 4, 4] instead of [1, 4] which of course you could solve by adding a distinct call after the filter. on another note, it would be sufficient to keep it as is if the OP wants to get the occurrence of a particular number in the list which requires some additional searching... so ultimately it might be better to proceed with OP's approach.
              – Aomine
              6 hours ago












            • @Aomine Indeed, if the eventual result is desired to just have the items distinct would help. Otherwise, if the sequence in which the duplicates occur matters, this can still be used. Added both for completeness.
              – nullpointer
              6 hours ago






            • 2




              Simpler in source code, but horrible regarding performance. The OP's original approach using groupingBy as starting point is much preferable.
              – Holger
              5 hours ago










            • @Holger Can you shed some details over the horrible regarding performance part. SInce I was considering that collecting to a Map using a stream and then performing operations would still be equal in performance.
              – nullpointer
              4 hours ago






            • 2




              indexOf and lastIndexOf are linear searches. You can even predict, that for unique elements, all elements of the list will be traversed when searching once from the beginning and once from the end, and you are repeating this for every element, so the worst case of your operation will be n×n. In case of frequency, which counts all occurrences, it will always be n×n. Whereas the filling of the map will always be n operations, even if hash operation are more costly and it bears allocations, but that's a fixed constant factor, not growing with the number of elements.
              – Holger
              4 hours ago















            up vote
            2
            down vote













            A simpler way to find that out could be



            List<String> recurringItems = list.stream()
            .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
            .collect(Collectors.toList());


            Since for items occurring more than once, lastIndex wouldn't be equal to the first index.





            Alternatively, you can use Collectors.toSet() to ensure the items are listed only once in case you are not interested in their order of recurrence.



            Set<String> recurringItemsOnce = list.stream()
            .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
            .collect(Collectors.toSet());


            Or using Collections.frequency as:



            Set<String> recurringItems = list.stream()
            .filter(item -> Collections.frequency(list, item) >= 2)
            .collect(Collectors.toSet());





            share|improve this answer























            • this would retrieve duplicate items, e.g. if our list was Arrays.asList("1","2","3","1","56","4","4") then as a result you'd have [1, 1, 4, 4] instead of [1, 4] which of course you could solve by adding a distinct call after the filter. on another note, it would be sufficient to keep it as is if the OP wants to get the occurrence of a particular number in the list which requires some additional searching... so ultimately it might be better to proceed with OP's approach.
              – Aomine
              6 hours ago












            • @Aomine Indeed, if the eventual result is desired to just have the items distinct would help. Otherwise, if the sequence in which the duplicates occur matters, this can still be used. Added both for completeness.
              – nullpointer
              6 hours ago






            • 2




              Simpler in source code, but horrible regarding performance. The OP's original approach using groupingBy as starting point is much preferable.
              – Holger
              5 hours ago










            • @Holger Can you shed some details over the horrible regarding performance part. SInce I was considering that collecting to a Map using a stream and then performing operations would still be equal in performance.
              – nullpointer
              4 hours ago






            • 2




              indexOf and lastIndexOf are linear searches. You can even predict, that for unique elements, all elements of the list will be traversed when searching once from the beginning and once from the end, and you are repeating this for every element, so the worst case of your operation will be n×n. In case of frequency, which counts all occurrences, it will always be n×n. Whereas the filling of the map will always be n operations, even if hash operation are more costly and it bears allocations, but that's a fixed constant factor, not growing with the number of elements.
              – Holger
              4 hours ago













            up vote
            2
            down vote










            up vote
            2
            down vote









            A simpler way to find that out could be



            List<String> recurringItems = list.stream()
            .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
            .collect(Collectors.toList());


            Since for items occurring more than once, lastIndex wouldn't be equal to the first index.





            Alternatively, you can use Collectors.toSet() to ensure the items are listed only once in case you are not interested in their order of recurrence.



            Set<String> recurringItemsOnce = list.stream()
            .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
            .collect(Collectors.toSet());


            Or using Collections.frequency as:



            Set<String> recurringItems = list.stream()
            .filter(item -> Collections.frequency(list, item) >= 2)
            .collect(Collectors.toSet());





            share|improve this answer














            A simpler way to find that out could be



            List<String> recurringItems = list.stream()
            .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
            .collect(Collectors.toList());


            Since for items occurring more than once, lastIndex wouldn't be equal to the first index.





            Alternatively, you can use Collectors.toSet() to ensure the items are listed only once in case you are not interested in their order of recurrence.



            Set<String> recurringItemsOnce = list.stream()
            .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
            .collect(Collectors.toSet());


            Or using Collections.frequency as:



            Set<String> recurringItems = list.stream()
            .filter(item -> Collections.frequency(list, item) >= 2)
            .collect(Collectors.toSet());






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 5 hours ago

























            answered 6 hours ago









            nullpointer

            36.5k1071143




            36.5k1071143












            • this would retrieve duplicate items, e.g. if our list was Arrays.asList("1","2","3","1","56","4","4") then as a result you'd have [1, 1, 4, 4] instead of [1, 4] which of course you could solve by adding a distinct call after the filter. on another note, it would be sufficient to keep it as is if the OP wants to get the occurrence of a particular number in the list which requires some additional searching... so ultimately it might be better to proceed with OP's approach.
              – Aomine
              6 hours ago












            • @Aomine Indeed, if the eventual result is desired to just have the items distinct would help. Otherwise, if the sequence in which the duplicates occur matters, this can still be used. Added both for completeness.
              – nullpointer
              6 hours ago






            • 2




              Simpler in source code, but horrible regarding performance. The OP's original approach using groupingBy as starting point is much preferable.
              – Holger
              5 hours ago










            • @Holger Can you shed some details over the horrible regarding performance part. SInce I was considering that collecting to a Map using a stream and then performing operations would still be equal in performance.
              – nullpointer
              4 hours ago






            • 2




              indexOf and lastIndexOf are linear searches. You can even predict, that for unique elements, all elements of the list will be traversed when searching once from the beginning and once from the end, and you are repeating this for every element, so the worst case of your operation will be n×n. In case of frequency, which counts all occurrences, it will always be n×n. Whereas the filling of the map will always be n operations, even if hash operation are more costly and it bears allocations, but that's a fixed constant factor, not growing with the number of elements.
              – Holger
              4 hours ago


















            • this would retrieve duplicate items, e.g. if our list was Arrays.asList("1","2","3","1","56","4","4") then as a result you'd have [1, 1, 4, 4] instead of [1, 4] which of course you could solve by adding a distinct call after the filter. on another note, it would be sufficient to keep it as is if the OP wants to get the occurrence of a particular number in the list which requires some additional searching... so ultimately it might be better to proceed with OP's approach.
              – Aomine
              6 hours ago












            • @Aomine Indeed, if the eventual result is desired to just have the items distinct would help. Otherwise, if the sequence in which the duplicates occur matters, this can still be used. Added both for completeness.
              – nullpointer
              6 hours ago






            • 2




              Simpler in source code, but horrible regarding performance. The OP's original approach using groupingBy as starting point is much preferable.
              – Holger
              5 hours ago










            • @Holger Can you shed some details over the horrible regarding performance part. SInce I was considering that collecting to a Map using a stream and then performing operations would still be equal in performance.
              – nullpointer
              4 hours ago






            • 2




              indexOf and lastIndexOf are linear searches. You can even predict, that for unique elements, all elements of the list will be traversed when searching once from the beginning and once from the end, and you are repeating this for every element, so the worst case of your operation will be n×n. In case of frequency, which counts all occurrences, it will always be n×n. Whereas the filling of the map will always be n operations, even if hash operation are more costly and it bears allocations, but that's a fixed constant factor, not growing with the number of elements.
              – Holger
              4 hours ago
















            this would retrieve duplicate items, e.g. if our list was Arrays.asList("1","2","3","1","56","4","4") then as a result you'd have [1, 1, 4, 4] instead of [1, 4] which of course you could solve by adding a distinct call after the filter. on another note, it would be sufficient to keep it as is if the OP wants to get the occurrence of a particular number in the list which requires some additional searching... so ultimately it might be better to proceed with OP's approach.
            – Aomine
            6 hours ago






            this would retrieve duplicate items, e.g. if our list was Arrays.asList("1","2","3","1","56","4","4") then as a result you'd have [1, 1, 4, 4] instead of [1, 4] which of course you could solve by adding a distinct call after the filter. on another note, it would be sufficient to keep it as is if the OP wants to get the occurrence of a particular number in the list which requires some additional searching... so ultimately it might be better to proceed with OP's approach.
            – Aomine
            6 hours ago














            @Aomine Indeed, if the eventual result is desired to just have the items distinct would help. Otherwise, if the sequence in which the duplicates occur matters, this can still be used. Added both for completeness.
            – nullpointer
            6 hours ago




            @Aomine Indeed, if the eventual result is desired to just have the items distinct would help. Otherwise, if the sequence in which the duplicates occur matters, this can still be used. Added both for completeness.
            – nullpointer
            6 hours ago




            2




            2




            Simpler in source code, but horrible regarding performance. The OP's original approach using groupingBy as starting point is much preferable.
            – Holger
            5 hours ago




            Simpler in source code, but horrible regarding performance. The OP's original approach using groupingBy as starting point is much preferable.
            – Holger
            5 hours ago












            @Holger Can you shed some details over the horrible regarding performance part. SInce I was considering that collecting to a Map using a stream and then performing operations would still be equal in performance.
            – nullpointer
            4 hours ago




            @Holger Can you shed some details over the horrible regarding performance part. SInce I was considering that collecting to a Map using a stream and then performing operations would still be equal in performance.
            – nullpointer
            4 hours ago




            2




            2




            indexOf and lastIndexOf are linear searches. You can even predict, that for unique elements, all elements of the list will be traversed when searching once from the beginning and once from the end, and you are repeating this for every element, so the worst case of your operation will be n×n. In case of frequency, which counts all occurrences, it will always be n×n. Whereas the filling of the map will always be n operations, even if hash operation are more costly and it bears allocations, but that's a fixed constant factor, not growing with the number of elements.
            – Holger
            4 hours ago




            indexOf and lastIndexOf are linear searches. You can even predict, that for unique elements, all elements of the list will be traversed when searching once from the beginning and once from the end, and you are repeating this for every element, so the worst case of your operation will be n×n. In case of frequency, which counts all occurrences, it will always be n×n. Whereas the filling of the map will always be n operations, even if hash operation are more costly and it bears allocations, but that's a fixed constant factor, not growing with the number of elements.
            – Holger
            4 hours ago










            Rishabh Chaturvedi is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            Rishabh Chaturvedi is a new contributor. Be nice, and check out our Code of Conduct.













            Rishabh Chaturvedi is a new contributor. Be nice, and check out our Code of Conduct.












            Rishabh Chaturvedi is a new contributor. Be nice, and check out our Code of Conduct.
















            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53584012%2ffind-only-repeated-string-attributes-in-list-with-java-8%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

            サソリ

            広島県道265号伴広島線

            Setup Asymptote in Texstudio