Get the Strings that occur exactly three times from Arraylist












6















I have an ArrayList which contains some values with duplicates and elements that occur thrice, I want to collect those values that occur thrice specifically into another ArrayList like



Arraylist<String> strings;   //contains all strings that are duplicates and that occur thrice


Here, I want to get only the Strings that occur thrice in another array list.



Arraylist<String> thrice;    //contains only elements that occur three times.


Currently, I have a solution for dealing with duplicates but I cannot extend this for only getting strings that occur thrice, this please help me to find out.










share|improve this question




















  • 1





    Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.

    – shash678
    Jan 2 at 16:31











  • See this answer for a solution as @shash678 suggested

    – Stalemate Of Tuning
    Jan 2 at 16:35











  • Possible duplicate of get the duplicates values from Arraylist<String> and then get those items in another Arraylist

    – Vipul Chauhan
    Jan 4 at 17:25
















6















I have an ArrayList which contains some values with duplicates and elements that occur thrice, I want to collect those values that occur thrice specifically into another ArrayList like



Arraylist<String> strings;   //contains all strings that are duplicates and that occur thrice


Here, I want to get only the Strings that occur thrice in another array list.



Arraylist<String> thrice;    //contains only elements that occur three times.


Currently, I have a solution for dealing with duplicates but I cannot extend this for only getting strings that occur thrice, this please help me to find out.










share|improve this question




















  • 1





    Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.

    – shash678
    Jan 2 at 16:31











  • See this answer for a solution as @shash678 suggested

    – Stalemate Of Tuning
    Jan 2 at 16:35











  • Possible duplicate of get the duplicates values from Arraylist<String> and then get those items in another Arraylist

    – Vipul Chauhan
    Jan 4 at 17:25














6












6








6








I have an ArrayList which contains some values with duplicates and elements that occur thrice, I want to collect those values that occur thrice specifically into another ArrayList like



Arraylist<String> strings;   //contains all strings that are duplicates and that occur thrice


Here, I want to get only the Strings that occur thrice in another array list.



Arraylist<String> thrice;    //contains only elements that occur three times.


Currently, I have a solution for dealing with duplicates but I cannot extend this for only getting strings that occur thrice, this please help me to find out.










share|improve this question
















I have an ArrayList which contains some values with duplicates and elements that occur thrice, I want to collect those values that occur thrice specifically into another ArrayList like



Arraylist<String> strings;   //contains all strings that are duplicates and that occur thrice


Here, I want to get only the Strings that occur thrice in another array list.



Arraylist<String> thrice;    //contains only elements that occur three times.


Currently, I have a solution for dealing with duplicates but I cannot extend this for only getting strings that occur thrice, this please help me to find out.







java list arraylist






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 8:34









Naman

45.1k11102204




45.1k11102204










asked Jan 2 at 16:29









Vipul ChauhanVipul Chauhan

383




383








  • 1





    Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.

    – shash678
    Jan 2 at 16:31











  • See this answer for a solution as @shash678 suggested

    – Stalemate Of Tuning
    Jan 2 at 16:35











  • Possible duplicate of get the duplicates values from Arraylist<String> and then get those items in another Arraylist

    – Vipul Chauhan
    Jan 4 at 17:25














  • 1





    Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.

    – shash678
    Jan 2 at 16:31











  • See this answer for a solution as @shash678 suggested

    – Stalemate Of Tuning
    Jan 2 at 16:35











  • Possible duplicate of get the duplicates values from Arraylist<String> and then get those items in another Arraylist

    – Vipul Chauhan
    Jan 4 at 17:25








1




1





Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.

– shash678
Jan 2 at 16:31





Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.

– shash678
Jan 2 at 16:31













See this answer for a solution as @shash678 suggested

– Stalemate Of Tuning
Jan 2 at 16:35





See this answer for a solution as @shash678 suggested

– Stalemate Of Tuning
Jan 2 at 16:35













Possible duplicate of get the duplicates values from Arraylist<String> and then get those items in another Arraylist

– Vipul Chauhan
Jan 4 at 17:25





Possible duplicate of get the duplicates values from Arraylist<String> and then get those items in another Arraylist

– Vipul Chauhan
Jan 4 at 17:25












5 Answers
5






active

oldest

votes


















0














A generic utility of what you're trying to acheieve in both the questions would be using Collections.frequency as :



/**
* @param input the list as your input
* @param n number of occurrence (duplicates:2 , triplets:3 etc..)
* @param <T> (type of elements)
* @return elements with such conditional occurrent in a Set
*/
static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
return input.stream()
.filter(a -> Collections.frequency(input, a) == n) // filter by number of occurrences
.collect(Collectors.toSet()); // collecting to a final set (one representation of each)
}


Note: This would be an O(n^2) approach since its using Collections.frequency which iterates over the entire collection again to get the frequency. But proposed for a more readable and generic approach towards what you're looking for. Also, this intentionally collects final output to a Set, since a List can again have duplicates after all.





Alternatively, you can use the method to count the frequency of elements in Java-8 and iterate over the entries of the Map created thereby to process filtering as desired and collect the output in the same iteration :



/**
* @param input the list as your input
* @param n number of occurrence (duplicates :2 , triplets :3 etc)
* @param <T> (type of elements)
* @return elements in a set
*/
static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
return input.stream() // Stream<T>
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting())) // Map<T, Long>
.entrySet() // Set<Map.Entry<T,Long>>
.stream() // Stream<Map.Entry<T,Long>>
.filter(e -> e.getValue() == n) // filtered with frequency 'n'
.map(Map.Entry::getKey) // Stream<T>
.collect(Collectors.toSet()); // collect to Set
}





share|improve this answer

































    3














    You can do it via a stream as follows:



     List<String> result = strings.stream()
    .collect(Collectors.groupingBy(Function.identity(), counting()))
    .entrySet().stream()
    .filter(e -> e.getValue() == 3) // keep only elements that occur 3 times
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());


    You could also do it as follows, but I'd recommend the above as it's more preferable.



    List<String> result = new HashSet<>(strings).stream()
    .filter(item -> strings.stream()
    .filter(e -> e.equals(item)).limit(3).count() == 3)
    .collect(Collectors.toList());





    share|improve this answer





















    • 1





      The second one doesn't seem really efficient, it has a O(n^2) time complexity for a problem which is easily solved in O(n), kind of overkill.

      – Ricola
      Jan 2 at 16:47













    • @Ricola First is definitely preferable. I'll edit to explicitly say so.

      – Aomine
      Jan 2 at 16:49



















    2














    Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.



    Furthermore, instead of writing a method for finding the strings that occur three times specifically, you could write a method that takes in a parameter, n and finds the strings that occur N times:



    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;

    class StackOverflowQ {

    static List<String> getStringsThatOccurNTimes(List<String> stringList, int n) {
    if (stringList == null || stringList.size() == 0) {
    return stringList;
    }
    Set<String> stringsThatOccurNTimesSet = new HashSet<>();
    Map<String, Integer> stringCounts = new HashMap<>();
    for (String s : stringList) {
    int currentStringCount = stringCounts.getOrDefault(s, 0) + 1;
    stringCounts.put(s, currentStringCount);
    if (currentStringCount == n) {
    stringsThatOccurNTimesSet.add(s);
    } else if (currentStringCount == n + 1) {
    stringsThatOccurNTimesSet.remove(s); // We use a set so this operation is O(1)
    }
    }
    return new ArrayList<>(stringsThatOccurNTimesSet);
    }

    public static void main(String args) {
    List<String> stringsList = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e", "b", "c", "c", "d", "d", "d", "e"));
    List<String> stringsThatOccurTwoTimes = getStringsThatOccurNTimes(stringsList, 2);
    List<String> stringsThatOccurThreeTimes = getStringsThatOccurNTimes(stringsList, 3);
    List<String> stringsThatOccurFourTimes = getStringsThatOccurNTimes(stringsList, 4);
    System.out.println("Original list: " + stringsList);
    System.out.println("Strings that occur two times: " + stringsThatOccurTwoTimes);
    System.out.println("Strings that occur three times: " + stringsThatOccurThreeTimes);
    System.out.println("Strings that occur four times: " + stringsThatOccurFourTimes);
    }

    }


    Output:



    Original list: [a, b, c, d, e, b, c, c, d, d, d, e]
    Strings that occur two times: [b, e]
    Strings that occur three times: [c]
    Strings that occur four times: [d]





    share|improve this answer


























    • How about a util for this in general?

      – Naman
      Jan 2 at 17:13













    • Nice I use something similar in python when I do interview questions that are similar to OP's one.

      – shash678
      Jan 2 at 17:28



















    1














    The best way to do this is.....



    Making of required arraylist.........



        ArrayList<String> thrice=new ArrayList<>();
    ArrayList<String> one=new ArrayList<>();


    Adding some values for checking.......



        one.add("1");one.add("1");one.add("1");one.add("1");one.add("1");
    one.add("2");one.add("2");one.add("2");one.add("2");one.add("2");
    one.add("1");one.add("1");one.add("1");
    one.add("3");one.add("3");
    one.add("4");one.add("5");
    one.add("2");one.add("2");one.add("2");


    Mapping to done the task.....



        Map<String, Integer> duplicates = new HashMap<String, Integer>();

    for (String str : one) {
    if (duplicates.containsKey(str)) {
    duplicates.put(str, duplicates.get(str) + 1);
    } else {
    duplicates.put(str, 1);
    }
    }

    for (Map.Entry<String, Integer> entry : duplicates.entrySet()) {

    if(entry.getValue()>=3){
    thrice.add(entry.getKey());
    }
    }


    Set the list in listview...



        ArrayAdapter<String> ad=new ArrayAdapter<> 
    (this,android.R.layout.simple_list_item_1,thrice);
    ListView lv=findViewById(R.id.new_l);
    lv.setAdapter(ad);


    Output= 1,2



    Already check the answer and you can change the condition according to your way



                               if(entry.getValue()>=3){
    thrice.add(entry.getKey());
    }


    Easiest answer from above...not required to change the versions of minimum sdk for android user






    share|improve this answer































      0














      You can use computeIfAbsent for this.



      List<String> strings;

      final Map<String, BigInteger> stringCounts = new HashMap<>();
      strings.stream().forEach(s -> {
      BigInteger count = stringCounts.computeIfAbsent(s, k -> BigInteger.ZERO).add(BigInteger.ONE);
      stringCounts.put(s, count);
      });


      Now filter stringCounts with value=3.






      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%2f54009836%2fget-the-strings-that-occur-exactly-three-times-from-arrayliststring%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        0














        A generic utility of what you're trying to acheieve in both the questions would be using Collections.frequency as :



        /**
        * @param input the list as your input
        * @param n number of occurrence (duplicates:2 , triplets:3 etc..)
        * @param <T> (type of elements)
        * @return elements with such conditional occurrent in a Set
        */
        static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
        return input.stream()
        .filter(a -> Collections.frequency(input, a) == n) // filter by number of occurrences
        .collect(Collectors.toSet()); // collecting to a final set (one representation of each)
        }


        Note: This would be an O(n^2) approach since its using Collections.frequency which iterates over the entire collection again to get the frequency. But proposed for a more readable and generic approach towards what you're looking for. Also, this intentionally collects final output to a Set, since a List can again have duplicates after all.





        Alternatively, you can use the method to count the frequency of elements in Java-8 and iterate over the entries of the Map created thereby to process filtering as desired and collect the output in the same iteration :



        /**
        * @param input the list as your input
        * @param n number of occurrence (duplicates :2 , triplets :3 etc)
        * @param <T> (type of elements)
        * @return elements in a set
        */
        static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
        return input.stream() // Stream<T>
        .collect(Collectors.groupingBy(Function.identity(),
        Collectors.counting())) // Map<T, Long>
        .entrySet() // Set<Map.Entry<T,Long>>
        .stream() // Stream<Map.Entry<T,Long>>
        .filter(e -> e.getValue() == n) // filtered with frequency 'n'
        .map(Map.Entry::getKey) // Stream<T>
        .collect(Collectors.toSet()); // collect to Set
        }





        share|improve this answer






























          0














          A generic utility of what you're trying to acheieve in both the questions would be using Collections.frequency as :



          /**
          * @param input the list as your input
          * @param n number of occurrence (duplicates:2 , triplets:3 etc..)
          * @param <T> (type of elements)
          * @return elements with such conditional occurrent in a Set
          */
          static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
          return input.stream()
          .filter(a -> Collections.frequency(input, a) == n) // filter by number of occurrences
          .collect(Collectors.toSet()); // collecting to a final set (one representation of each)
          }


          Note: This would be an O(n^2) approach since its using Collections.frequency which iterates over the entire collection again to get the frequency. But proposed for a more readable and generic approach towards what you're looking for. Also, this intentionally collects final output to a Set, since a List can again have duplicates after all.





          Alternatively, you can use the method to count the frequency of elements in Java-8 and iterate over the entries of the Map created thereby to process filtering as desired and collect the output in the same iteration :



          /**
          * @param input the list as your input
          * @param n number of occurrence (duplicates :2 , triplets :3 etc)
          * @param <T> (type of elements)
          * @return elements in a set
          */
          static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
          return input.stream() // Stream<T>
          .collect(Collectors.groupingBy(Function.identity(),
          Collectors.counting())) // Map<T, Long>
          .entrySet() // Set<Map.Entry<T,Long>>
          .stream() // Stream<Map.Entry<T,Long>>
          .filter(e -> e.getValue() == n) // filtered with frequency 'n'
          .map(Map.Entry::getKey) // Stream<T>
          .collect(Collectors.toSet()); // collect to Set
          }





          share|improve this answer




























            0












            0








            0







            A generic utility of what you're trying to acheieve in both the questions would be using Collections.frequency as :



            /**
            * @param input the list as your input
            * @param n number of occurrence (duplicates:2 , triplets:3 etc..)
            * @param <T> (type of elements)
            * @return elements with such conditional occurrent in a Set
            */
            static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
            return input.stream()
            .filter(a -> Collections.frequency(input, a) == n) // filter by number of occurrences
            .collect(Collectors.toSet()); // collecting to a final set (one representation of each)
            }


            Note: This would be an O(n^2) approach since its using Collections.frequency which iterates over the entire collection again to get the frequency. But proposed for a more readable and generic approach towards what you're looking for. Also, this intentionally collects final output to a Set, since a List can again have duplicates after all.





            Alternatively, you can use the method to count the frequency of elements in Java-8 and iterate over the entries of the Map created thereby to process filtering as desired and collect the output in the same iteration :



            /**
            * @param input the list as your input
            * @param n number of occurrence (duplicates :2 , triplets :3 etc)
            * @param <T> (type of elements)
            * @return elements in a set
            */
            static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
            return input.stream() // Stream<T>
            .collect(Collectors.groupingBy(Function.identity(),
            Collectors.counting())) // Map<T, Long>
            .entrySet() // Set<Map.Entry<T,Long>>
            .stream() // Stream<Map.Entry<T,Long>>
            .filter(e -> e.getValue() == n) // filtered with frequency 'n'
            .map(Map.Entry::getKey) // Stream<T>
            .collect(Collectors.toSet()); // collect to Set
            }





            share|improve this answer















            A generic utility of what you're trying to acheieve in both the questions would be using Collections.frequency as :



            /**
            * @param input the list as your input
            * @param n number of occurrence (duplicates:2 , triplets:3 etc..)
            * @param <T> (type of elements)
            * @return elements with such conditional occurrent in a Set
            */
            static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
            return input.stream()
            .filter(a -> Collections.frequency(input, a) == n) // filter by number of occurrences
            .collect(Collectors.toSet()); // collecting to a final set (one representation of each)
            }


            Note: This would be an O(n^2) approach since its using Collections.frequency which iterates over the entire collection again to get the frequency. But proposed for a more readable and generic approach towards what you're looking for. Also, this intentionally collects final output to a Set, since a List can again have duplicates after all.





            Alternatively, you can use the method to count the frequency of elements in Java-8 and iterate over the entries of the Map created thereby to process filtering as desired and collect the output in the same iteration :



            /**
            * @param input the list as your input
            * @param n number of occurrence (duplicates :2 , triplets :3 etc)
            * @param <T> (type of elements)
            * @return elements in a set
            */
            static <T> Set<T> findElementsWithNOccurrence(List<T> input, int n) {
            return input.stream() // Stream<T>
            .collect(Collectors.groupingBy(Function.identity(),
            Collectors.counting())) // Map<T, Long>
            .entrySet() // Set<Map.Entry<T,Long>>
            .stream() // Stream<Map.Entry<T,Long>>
            .filter(e -> e.getValue() == n) // filtered with frequency 'n'
            .map(Map.Entry::getKey) // Stream<T>
            .collect(Collectors.toSet()); // collect to Set
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 2 at 17:37

























            answered Jan 2 at 17:10









            NamanNaman

            45.1k11102204




            45.1k11102204

























                3














                You can do it via a stream as follows:



                 List<String> result = strings.stream()
                .collect(Collectors.groupingBy(Function.identity(), counting()))
                .entrySet().stream()
                .filter(e -> e.getValue() == 3) // keep only elements that occur 3 times
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());


                You could also do it as follows, but I'd recommend the above as it's more preferable.



                List<String> result = new HashSet<>(strings).stream()
                .filter(item -> strings.stream()
                .filter(e -> e.equals(item)).limit(3).count() == 3)
                .collect(Collectors.toList());





                share|improve this answer





















                • 1





                  The second one doesn't seem really efficient, it has a O(n^2) time complexity for a problem which is easily solved in O(n), kind of overkill.

                  – Ricola
                  Jan 2 at 16:47













                • @Ricola First is definitely preferable. I'll edit to explicitly say so.

                  – Aomine
                  Jan 2 at 16:49
















                3














                You can do it via a stream as follows:



                 List<String> result = strings.stream()
                .collect(Collectors.groupingBy(Function.identity(), counting()))
                .entrySet().stream()
                .filter(e -> e.getValue() == 3) // keep only elements that occur 3 times
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());


                You could also do it as follows, but I'd recommend the above as it's more preferable.



                List<String> result = new HashSet<>(strings).stream()
                .filter(item -> strings.stream()
                .filter(e -> e.equals(item)).limit(3).count() == 3)
                .collect(Collectors.toList());





                share|improve this answer





















                • 1





                  The second one doesn't seem really efficient, it has a O(n^2) time complexity for a problem which is easily solved in O(n), kind of overkill.

                  – Ricola
                  Jan 2 at 16:47













                • @Ricola First is definitely preferable. I'll edit to explicitly say so.

                  – Aomine
                  Jan 2 at 16:49














                3












                3








                3







                You can do it via a stream as follows:



                 List<String> result = strings.stream()
                .collect(Collectors.groupingBy(Function.identity(), counting()))
                .entrySet().stream()
                .filter(e -> e.getValue() == 3) // keep only elements that occur 3 times
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());


                You could also do it as follows, but I'd recommend the above as it's more preferable.



                List<String> result = new HashSet<>(strings).stream()
                .filter(item -> strings.stream()
                .filter(e -> e.equals(item)).limit(3).count() == 3)
                .collect(Collectors.toList());





                share|improve this answer















                You can do it via a stream as follows:



                 List<String> result = strings.stream()
                .collect(Collectors.groupingBy(Function.identity(), counting()))
                .entrySet().stream()
                .filter(e -> e.getValue() == 3) // keep only elements that occur 3 times
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());


                You could also do it as follows, but I'd recommend the above as it's more preferable.



                List<String> result = new HashSet<>(strings).stream()
                .filter(item -> strings.stream()
                .filter(e -> e.equals(item)).limit(3).count() == 3)
                .collect(Collectors.toList());






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 2 at 16:51

























                answered Jan 2 at 16:36









                AomineAomine

                42.6k74677




                42.6k74677








                • 1





                  The second one doesn't seem really efficient, it has a O(n^2) time complexity for a problem which is easily solved in O(n), kind of overkill.

                  – Ricola
                  Jan 2 at 16:47













                • @Ricola First is definitely preferable. I'll edit to explicitly say so.

                  – Aomine
                  Jan 2 at 16:49














                • 1





                  The second one doesn't seem really efficient, it has a O(n^2) time complexity for a problem which is easily solved in O(n), kind of overkill.

                  – Ricola
                  Jan 2 at 16:47













                • @Ricola First is definitely preferable. I'll edit to explicitly say so.

                  – Aomine
                  Jan 2 at 16:49








                1




                1





                The second one doesn't seem really efficient, it has a O(n^2) time complexity for a problem which is easily solved in O(n), kind of overkill.

                – Ricola
                Jan 2 at 16:47







                The second one doesn't seem really efficient, it has a O(n^2) time complexity for a problem which is easily solved in O(n), kind of overkill.

                – Ricola
                Jan 2 at 16:47















                @Ricola First is definitely preferable. I'll edit to explicitly say so.

                – Aomine
                Jan 2 at 16:49





                @Ricola First is definitely preferable. I'll edit to explicitly say so.

                – Aomine
                Jan 2 at 16:49











                2














                Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.



                Furthermore, instead of writing a method for finding the strings that occur three times specifically, you could write a method that takes in a parameter, n and finds the strings that occur N times:



                import java.util.ArrayList;
                import java.util.Arrays;
                import java.util.HashMap;
                import java.util.HashSet;
                import java.util.List;
                import java.util.Map;
                import java.util.Set;

                class StackOverflowQ {

                static List<String> getStringsThatOccurNTimes(List<String> stringList, int n) {
                if (stringList == null || stringList.size() == 0) {
                return stringList;
                }
                Set<String> stringsThatOccurNTimesSet = new HashSet<>();
                Map<String, Integer> stringCounts = new HashMap<>();
                for (String s : stringList) {
                int currentStringCount = stringCounts.getOrDefault(s, 0) + 1;
                stringCounts.put(s, currentStringCount);
                if (currentStringCount == n) {
                stringsThatOccurNTimesSet.add(s);
                } else if (currentStringCount == n + 1) {
                stringsThatOccurNTimesSet.remove(s); // We use a set so this operation is O(1)
                }
                }
                return new ArrayList<>(stringsThatOccurNTimesSet);
                }

                public static void main(String args) {
                List<String> stringsList = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e", "b", "c", "c", "d", "d", "d", "e"));
                List<String> stringsThatOccurTwoTimes = getStringsThatOccurNTimes(stringsList, 2);
                List<String> stringsThatOccurThreeTimes = getStringsThatOccurNTimes(stringsList, 3);
                List<String> stringsThatOccurFourTimes = getStringsThatOccurNTimes(stringsList, 4);
                System.out.println("Original list: " + stringsList);
                System.out.println("Strings that occur two times: " + stringsThatOccurTwoTimes);
                System.out.println("Strings that occur three times: " + stringsThatOccurThreeTimes);
                System.out.println("Strings that occur four times: " + stringsThatOccurFourTimes);
                }

                }


                Output:



                Original list: [a, b, c, d, e, b, c, c, d, d, d, e]
                Strings that occur two times: [b, e]
                Strings that occur three times: [c]
                Strings that occur four times: [d]





                share|improve this answer


























                • How about a util for this in general?

                  – Naman
                  Jan 2 at 17:13













                • Nice I use something similar in python when I do interview questions that are similar to OP's one.

                  – shash678
                  Jan 2 at 17:28
















                2














                Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.



                Furthermore, instead of writing a method for finding the strings that occur three times specifically, you could write a method that takes in a parameter, n and finds the strings that occur N times:



                import java.util.ArrayList;
                import java.util.Arrays;
                import java.util.HashMap;
                import java.util.HashSet;
                import java.util.List;
                import java.util.Map;
                import java.util.Set;

                class StackOverflowQ {

                static List<String> getStringsThatOccurNTimes(List<String> stringList, int n) {
                if (stringList == null || stringList.size() == 0) {
                return stringList;
                }
                Set<String> stringsThatOccurNTimesSet = new HashSet<>();
                Map<String, Integer> stringCounts = new HashMap<>();
                for (String s : stringList) {
                int currentStringCount = stringCounts.getOrDefault(s, 0) + 1;
                stringCounts.put(s, currentStringCount);
                if (currentStringCount == n) {
                stringsThatOccurNTimesSet.add(s);
                } else if (currentStringCount == n + 1) {
                stringsThatOccurNTimesSet.remove(s); // We use a set so this operation is O(1)
                }
                }
                return new ArrayList<>(stringsThatOccurNTimesSet);
                }

                public static void main(String args) {
                List<String> stringsList = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e", "b", "c", "c", "d", "d", "d", "e"));
                List<String> stringsThatOccurTwoTimes = getStringsThatOccurNTimes(stringsList, 2);
                List<String> stringsThatOccurThreeTimes = getStringsThatOccurNTimes(stringsList, 3);
                List<String> stringsThatOccurFourTimes = getStringsThatOccurNTimes(stringsList, 4);
                System.out.println("Original list: " + stringsList);
                System.out.println("Strings that occur two times: " + stringsThatOccurTwoTimes);
                System.out.println("Strings that occur three times: " + stringsThatOccurThreeTimes);
                System.out.println("Strings that occur four times: " + stringsThatOccurFourTimes);
                }

                }


                Output:



                Original list: [a, b, c, d, e, b, c, c, d, d, d, e]
                Strings that occur two times: [b, e]
                Strings that occur three times: [c]
                Strings that occur four times: [d]





                share|improve this answer


























                • How about a util for this in general?

                  – Naman
                  Jan 2 at 17:13













                • Nice I use something similar in python when I do interview questions that are similar to OP's one.

                  – shash678
                  Jan 2 at 17:28














                2












                2








                2







                Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.



                Furthermore, instead of writing a method for finding the strings that occur three times specifically, you could write a method that takes in a parameter, n and finds the strings that occur N times:



                import java.util.ArrayList;
                import java.util.Arrays;
                import java.util.HashMap;
                import java.util.HashSet;
                import java.util.List;
                import java.util.Map;
                import java.util.Set;

                class StackOverflowQ {

                static List<String> getStringsThatOccurNTimes(List<String> stringList, int n) {
                if (stringList == null || stringList.size() == 0) {
                return stringList;
                }
                Set<String> stringsThatOccurNTimesSet = new HashSet<>();
                Map<String, Integer> stringCounts = new HashMap<>();
                for (String s : stringList) {
                int currentStringCount = stringCounts.getOrDefault(s, 0) + 1;
                stringCounts.put(s, currentStringCount);
                if (currentStringCount == n) {
                stringsThatOccurNTimesSet.add(s);
                } else if (currentStringCount == n + 1) {
                stringsThatOccurNTimesSet.remove(s); // We use a set so this operation is O(1)
                }
                }
                return new ArrayList<>(stringsThatOccurNTimesSet);
                }

                public static void main(String args) {
                List<String> stringsList = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e", "b", "c", "c", "d", "d", "d", "e"));
                List<String> stringsThatOccurTwoTimes = getStringsThatOccurNTimes(stringsList, 2);
                List<String> stringsThatOccurThreeTimes = getStringsThatOccurNTimes(stringsList, 3);
                List<String> stringsThatOccurFourTimes = getStringsThatOccurNTimes(stringsList, 4);
                System.out.println("Original list: " + stringsList);
                System.out.println("Strings that occur two times: " + stringsThatOccurTwoTimes);
                System.out.println("Strings that occur three times: " + stringsThatOccurThreeTimes);
                System.out.println("Strings that occur four times: " + stringsThatOccurFourTimes);
                }

                }


                Output:



                Original list: [a, b, c, d, e, b, c, c, d, d, d, e]
                Strings that occur two times: [b, e]
                Strings that occur three times: [c]
                Strings that occur four times: [d]





                share|improve this answer















                Basically, instead of using a HashSet you now want to use a HashMap to count the number of occurrences of each string.



                Furthermore, instead of writing a method for finding the strings that occur three times specifically, you could write a method that takes in a parameter, n and finds the strings that occur N times:



                import java.util.ArrayList;
                import java.util.Arrays;
                import java.util.HashMap;
                import java.util.HashSet;
                import java.util.List;
                import java.util.Map;
                import java.util.Set;

                class StackOverflowQ {

                static List<String> getStringsThatOccurNTimes(List<String> stringList, int n) {
                if (stringList == null || stringList.size() == 0) {
                return stringList;
                }
                Set<String> stringsThatOccurNTimesSet = new HashSet<>();
                Map<String, Integer> stringCounts = new HashMap<>();
                for (String s : stringList) {
                int currentStringCount = stringCounts.getOrDefault(s, 0) + 1;
                stringCounts.put(s, currentStringCount);
                if (currentStringCount == n) {
                stringsThatOccurNTimesSet.add(s);
                } else if (currentStringCount == n + 1) {
                stringsThatOccurNTimesSet.remove(s); // We use a set so this operation is O(1)
                }
                }
                return new ArrayList<>(stringsThatOccurNTimesSet);
                }

                public static void main(String args) {
                List<String> stringsList = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e", "b", "c", "c", "d", "d", "d", "e"));
                List<String> stringsThatOccurTwoTimes = getStringsThatOccurNTimes(stringsList, 2);
                List<String> stringsThatOccurThreeTimes = getStringsThatOccurNTimes(stringsList, 3);
                List<String> stringsThatOccurFourTimes = getStringsThatOccurNTimes(stringsList, 4);
                System.out.println("Original list: " + stringsList);
                System.out.println("Strings that occur two times: " + stringsThatOccurTwoTimes);
                System.out.println("Strings that occur three times: " + stringsThatOccurThreeTimes);
                System.out.println("Strings that occur four times: " + stringsThatOccurFourTimes);
                }

                }


                Output:



                Original list: [a, b, c, d, e, b, c, c, d, d, d, e]
                Strings that occur two times: [b, e]
                Strings that occur three times: [c]
                Strings that occur four times: [d]






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 4 at 14:54

























                answered Jan 2 at 16:35









                shash678shash678

                5,93521030




                5,93521030













                • How about a util for this in general?

                  – Naman
                  Jan 2 at 17:13













                • Nice I use something similar in python when I do interview questions that are similar to OP's one.

                  – shash678
                  Jan 2 at 17:28



















                • How about a util for this in general?

                  – Naman
                  Jan 2 at 17:13













                • Nice I use something similar in python when I do interview questions that are similar to OP's one.

                  – shash678
                  Jan 2 at 17:28

















                How about a util for this in general?

                – Naman
                Jan 2 at 17:13







                How about a util for this in general?

                – Naman
                Jan 2 at 17:13















                Nice I use something similar in python when I do interview questions that are similar to OP's one.

                – shash678
                Jan 2 at 17:28





                Nice I use something similar in python when I do interview questions that are similar to OP's one.

                – shash678
                Jan 2 at 17:28











                1














                The best way to do this is.....



                Making of required arraylist.........



                    ArrayList<String> thrice=new ArrayList<>();
                ArrayList<String> one=new ArrayList<>();


                Adding some values for checking.......



                    one.add("1");one.add("1");one.add("1");one.add("1");one.add("1");
                one.add("2");one.add("2");one.add("2");one.add("2");one.add("2");
                one.add("1");one.add("1");one.add("1");
                one.add("3");one.add("3");
                one.add("4");one.add("5");
                one.add("2");one.add("2");one.add("2");


                Mapping to done the task.....



                    Map<String, Integer> duplicates = new HashMap<String, Integer>();

                for (String str : one) {
                if (duplicates.containsKey(str)) {
                duplicates.put(str, duplicates.get(str) + 1);
                } else {
                duplicates.put(str, 1);
                }
                }

                for (Map.Entry<String, Integer> entry : duplicates.entrySet()) {

                if(entry.getValue()>=3){
                thrice.add(entry.getKey());
                }
                }


                Set the list in listview...



                    ArrayAdapter<String> ad=new ArrayAdapter<> 
                (this,android.R.layout.simple_list_item_1,thrice);
                ListView lv=findViewById(R.id.new_l);
                lv.setAdapter(ad);


                Output= 1,2



                Already check the answer and you can change the condition according to your way



                                           if(entry.getValue()>=3){
                thrice.add(entry.getKey());
                }


                Easiest answer from above...not required to change the versions of minimum sdk for android user






                share|improve this answer




























                  1














                  The best way to do this is.....



                  Making of required arraylist.........



                      ArrayList<String> thrice=new ArrayList<>();
                  ArrayList<String> one=new ArrayList<>();


                  Adding some values for checking.......



                      one.add("1");one.add("1");one.add("1");one.add("1");one.add("1");
                  one.add("2");one.add("2");one.add("2");one.add("2");one.add("2");
                  one.add("1");one.add("1");one.add("1");
                  one.add("3");one.add("3");
                  one.add("4");one.add("5");
                  one.add("2");one.add("2");one.add("2");


                  Mapping to done the task.....



                      Map<String, Integer> duplicates = new HashMap<String, Integer>();

                  for (String str : one) {
                  if (duplicates.containsKey(str)) {
                  duplicates.put(str, duplicates.get(str) + 1);
                  } else {
                  duplicates.put(str, 1);
                  }
                  }

                  for (Map.Entry<String, Integer> entry : duplicates.entrySet()) {

                  if(entry.getValue()>=3){
                  thrice.add(entry.getKey());
                  }
                  }


                  Set the list in listview...



                      ArrayAdapter<String> ad=new ArrayAdapter<> 
                  (this,android.R.layout.simple_list_item_1,thrice);
                  ListView lv=findViewById(R.id.new_l);
                  lv.setAdapter(ad);


                  Output= 1,2



                  Already check the answer and you can change the condition according to your way



                                             if(entry.getValue()>=3){
                  thrice.add(entry.getKey());
                  }


                  Easiest answer from above...not required to change the versions of minimum sdk for android user






                  share|improve this answer


























                    1












                    1








                    1







                    The best way to do this is.....



                    Making of required arraylist.........



                        ArrayList<String> thrice=new ArrayList<>();
                    ArrayList<String> one=new ArrayList<>();


                    Adding some values for checking.......



                        one.add("1");one.add("1");one.add("1");one.add("1");one.add("1");
                    one.add("2");one.add("2");one.add("2");one.add("2");one.add("2");
                    one.add("1");one.add("1");one.add("1");
                    one.add("3");one.add("3");
                    one.add("4");one.add("5");
                    one.add("2");one.add("2");one.add("2");


                    Mapping to done the task.....



                        Map<String, Integer> duplicates = new HashMap<String, Integer>();

                    for (String str : one) {
                    if (duplicates.containsKey(str)) {
                    duplicates.put(str, duplicates.get(str) + 1);
                    } else {
                    duplicates.put(str, 1);
                    }
                    }

                    for (Map.Entry<String, Integer> entry : duplicates.entrySet()) {

                    if(entry.getValue()>=3){
                    thrice.add(entry.getKey());
                    }
                    }


                    Set the list in listview...



                        ArrayAdapter<String> ad=new ArrayAdapter<> 
                    (this,android.R.layout.simple_list_item_1,thrice);
                    ListView lv=findViewById(R.id.new_l);
                    lv.setAdapter(ad);


                    Output= 1,2



                    Already check the answer and you can change the condition according to your way



                                               if(entry.getValue()>=3){
                    thrice.add(entry.getKey());
                    }


                    Easiest answer from above...not required to change the versions of minimum sdk for android user






                    share|improve this answer













                    The best way to do this is.....



                    Making of required arraylist.........



                        ArrayList<String> thrice=new ArrayList<>();
                    ArrayList<String> one=new ArrayList<>();


                    Adding some values for checking.......



                        one.add("1");one.add("1");one.add("1");one.add("1");one.add("1");
                    one.add("2");one.add("2");one.add("2");one.add("2");one.add("2");
                    one.add("1");one.add("1");one.add("1");
                    one.add("3");one.add("3");
                    one.add("4");one.add("5");
                    one.add("2");one.add("2");one.add("2");


                    Mapping to done the task.....



                        Map<String, Integer> duplicates = new HashMap<String, Integer>();

                    for (String str : one) {
                    if (duplicates.containsKey(str)) {
                    duplicates.put(str, duplicates.get(str) + 1);
                    } else {
                    duplicates.put(str, 1);
                    }
                    }

                    for (Map.Entry<String, Integer> entry : duplicates.entrySet()) {

                    if(entry.getValue()>=3){
                    thrice.add(entry.getKey());
                    }
                    }


                    Set the list in listview...



                        ArrayAdapter<String> ad=new ArrayAdapter<> 
                    (this,android.R.layout.simple_list_item_1,thrice);
                    ListView lv=findViewById(R.id.new_l);
                    lv.setAdapter(ad);


                    Output= 1,2



                    Already check the answer and you can change the condition according to your way



                                               if(entry.getValue()>=3){
                    thrice.add(entry.getKey());
                    }


                    Easiest answer from above...not required to change the versions of minimum sdk for android user







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jan 5 at 7:10









                    Vipul ChauhanVipul Chauhan

                    4310




                    4310























                        0














                        You can use computeIfAbsent for this.



                        List<String> strings;

                        final Map<String, BigInteger> stringCounts = new HashMap<>();
                        strings.stream().forEach(s -> {
                        BigInteger count = stringCounts.computeIfAbsent(s, k -> BigInteger.ZERO).add(BigInteger.ONE);
                        stringCounts.put(s, count);
                        });


                        Now filter stringCounts with value=3.






                        share|improve this answer




























                          0














                          You can use computeIfAbsent for this.



                          List<String> strings;

                          final Map<String, BigInteger> stringCounts = new HashMap<>();
                          strings.stream().forEach(s -> {
                          BigInteger count = stringCounts.computeIfAbsent(s, k -> BigInteger.ZERO).add(BigInteger.ONE);
                          stringCounts.put(s, count);
                          });


                          Now filter stringCounts with value=3.






                          share|improve this answer


























                            0












                            0








                            0







                            You can use computeIfAbsent for this.



                            List<String> strings;

                            final Map<String, BigInteger> stringCounts = new HashMap<>();
                            strings.stream().forEach(s -> {
                            BigInteger count = stringCounts.computeIfAbsent(s, k -> BigInteger.ZERO).add(BigInteger.ONE);
                            stringCounts.put(s, count);
                            });


                            Now filter stringCounts with value=3.






                            share|improve this answer













                            You can use computeIfAbsent for this.



                            List<String> strings;

                            final Map<String, BigInteger> stringCounts = new HashMap<>();
                            strings.stream().forEach(s -> {
                            BigInteger count = stringCounts.computeIfAbsent(s, k -> BigInteger.ZERO).add(BigInteger.ONE);
                            stringCounts.put(s, count);
                            });


                            Now filter stringCounts with value=3.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jan 2 at 17:06









                            fastcodejavafastcodejava

                            24.6k19109162




                            24.6k19109162






























                                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%2f54009836%2fget-the-strings-that-occur-exactly-three-times-from-arrayliststring%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

                                MongoDB - Not Authorized To Execute Command

                                How to fix TextFormField cause rebuild widget in Flutter

                                Npm cannot find a required file even through it is in the searched directory