1
public String count(String input, String... words) {
    List<String> wordList = Arrays.asList(words);
    Map<String, Long> maps = Arrays.asList(input.split(SPACE)).stream()
            .collect(groupingBy(Function.identity(), counting()));
    long number = 0;
    StringJoiner stringJoiner = new StringJoiner(System.lineSeparator());
    String s =    maps.entrySet().stream()
            .map(entry -> wordList.contains(entry.getKey()) ? entry.getKey() + ":" + entry.getValue() : ""+number + entry.getValue()).collect(Collectors.joining(System.lineSeparator()));
    stringJoiner.add(s);
    stringJoiner.add(NUMBER + number);
    return stringJoiner.toString();
}

As you can see from the above code I have string input like this "1 2 hello luck 5 hello 7 luck hello 10 11 luck" and the words array has hello, luck.

I want to search the string like this numbers: 6, hello:3, luck:3

I am trying this using the above code, but it does not do it for some reason, please can someone help?

1 Answer 1

1

You forgot to include groupingBy() and counting() function. Also SPACE and NUMBER are missing, so I assumed they represent " " and "numbers".

I made a bigger modification due to missing functions -> I collected the string values and number of their occurences in "maps", and also added the number of occurences of numbers (manually added "numbers" key to "maps"). The function works as you wanted.

public String count(String input, String... words)
{
    List<String> wordList = Arrays.asList(words);
    Map<String, Long> maps = new HashMap<>();
    // count the number of occurences of each word and all the numbers in the "Input" argument, and save word as
    // key, number as value
    Arrays.asList(input.split(" ")).stream()
            .forEach(str -> {
                if (maps.containsKey(str))
                {
                    // it's a string already contained in map
                    Long l = maps.get(str);
                    maps.put(str, ++l);
                }
                else
                {
                    try
                    {
                        Long parse = Long.parseLong(str);
                        // it's a number
                        if (maps.containsKey("numbers"))
                        {
                            Long l = maps.get("numbers");
                            maps.put("numbers", ++l);
                        }
                        else
                        {
                            // first number added
                            maps.put("numbers", (long) 1);
                        }
                    }
                    catch (NumberFormatException e)
                    {
                        // it's a string, not yet added to map
                        maps.put(str, (long) 1);
                    }
                }
            });
    StringJoiner stringJoiner = new StringJoiner(System.lineSeparator());
    String s = maps.entrySet().stream()
            // first we filter out words
            .filter(entry -> wordList.contains(entry.getKey()))
            // then we convert filtered words and value to string
            .map(entry -> entry.getKey() + ":" + entry.getValue())
            // collect
            .collect(Collectors.joining(System.lineSeparator()));
    stringJoiner.add(s);
    // add numbers at the end
    stringJoiner.add("numbers:" + maps.get("numbers"));
    return stringJoiner.toString();
}

EDIT: I realized that missing methods come from Collectors class (Collectors.groupingBy and Collectors.counting). I tried to repair your code with new information, but I can't see a nice solution to this other than the function I wrote above.

The problem lies in counting the number of numbers in the given input. You cannot increment variable "long number" inside .map or .filter function of stream, as the variable must be final or effectively final there. Besides, in any way, you would need to do a try catch block. Thus, I believe my solution with sorting everything into Map along with number of occurrences, then filtering this map for searched words ("words" parameter), and finally adding manually the "numbers" occurrence is a good solution.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.