Java 8使用多个列表进行流式处理和过滤

时间:2016-08-23 08:34:06

标签: lambda java-8 java-stream

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();
}

从上面的代码中我可以看到我有这样的字符串输入“1 2你好运气5你好7运气你好10 11运气”和单词数组有你好,运气。

我想像这个数字一样搜索字符串:6,你好:3,运气:3

我正在尝试使用上面的代码,但由于某些原因它没有这样做,请有人帮忙吗?

1 个答案:

答案 0 :(得分:1)

您忘记包含groupingBy()和counting()函数。还缺少SPACE和NUMBER,所以我认为它们代表“”和“数字”。

由于缺少功能,我做了一个更大的修改 - &gt;我在“地图”中收集了字符串值和它们出现的次数,并且还添加了数字的出现次数(手动将“数字”键添加到“地图”)。该功能可以根据需要使用。

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();
}

编辑:我意识到丢失的方法来自Collectors类(Collectors.groupingBy和Collectors.counting)。我尝试用新信息修复你的代码,但除了上面写的函数之外,我看不到一个很好的解决方案。

问题在于计算给定输入中的数字数量。你不能在流的.map或.filter函数内增加变量“long number”,因为变量必须是final或者有效的final。此外,无论如何,你需要做一个try catch块。因此,我相信我的解决方案是将所有内容排序到Map以及出现次数,然后过滤此映射以搜索单词(“单词”参数),最后手动添加“数字”出现是一个很好的解决方案。