如何将字符串列表中的数据转换为 Map使用流 API?

发布于 2025-01-18 11:02:49 字数 541 浏览 1 评论 0原文

我尝试使用 Stream API 将字符串列表中的数据转换为 Map

但我这样做的方式不正确:

public static Map<String, Integer> converter (List<String> data){
        return data.stream().collect(Collectors.toMap(e->e, Function.identity()));

如果我们有 List.of("5", "7", "5", "8", "9", "8")

任务 1 作为键 - 字符串,值 - 字符频率

任务 2 Strong> 作为键 - String 和值 - 字符串转换为整数

I tried to convert data from the list of strings into a Map<String, Integer> with the Stream API.

But the way I did it is not correct:

public static Map<String, Integer> converter (List<String> data){
        return data.stream().collect(Collectors.toMap(e->e, Function.identity()));

If we have List.of("5", "7", "5", "8", "9", "8")

task №1 as key - String, and value - character frequency

task №2 as key - String, and value - string converted to integer

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

难如初 2025-01-25 11:02:49

尝试这样的频率。请注意,映射不能有重复的键。

List<String> list2 = List.of("5", "7", "5", "8", "9","8");
  • keyString
  • 1开头。
  • Integers::sum 为每次出现的情况添加 1
Map<String, Integer> freq = list2.stream().collect(Collectors.toMap(
         e->e, (a)->1, Integer::sum));

freq.entrySet().forEach(System.out::println);

对于第二个任务,将字符串

5=2
7=1
8=2
9=1

转换为ints很简单。但请记住,重复项不可能存在,因此必须正确合并它们。这与第一个任务类似,只是我们不进行计数,而是将其转换为整数。由于您有重复的整数,因此您需要提供有关操作的说明。这就是merge 函数(a,b)->a,它表示现有值a 和新值b,只需保留 a

List<String> list2 = List.of("5", "7", "5", "8", "9","8");
Map<String, Integer> map = list2.stream().collectCollectors.toMap(e->e,
              Integer::valueOf,
              (a,b)->a); // just keep the first one

打印

5=5
7=7
8=8
9=9

Try it like this for a frequency. Note that a map can't have duplicate keys.

List<String> list2 = List.of("5", "7", "5", "8", "9","8");
  • the key is the String.
  • the value starts a 1.
  • the Integers::sum adds 1 for every occurrence.
Map<String, Integer> freq = list2.stream().collect(Collectors.toMap(
         e->e, (a)->1, Integer::sum));

freq.entrySet().forEach(System.out::println);

prints

5=2
7=1
8=2
9=1

for the second task, to convert the strings to ints is trivial. But remember that dups can't exist so they have to be properly merged. This is similar to the first task except instead of counting we're just converting to an integer. Since you have duplicate integers, you need to provide instructions on what to do. That is the merge function (a,b)->a which says for existing value a and new value b, just keep a

List<String> list2 = List.of("5", "7", "5", "8", "9","8");
Map<String, Integer> map = list2.stream().collectCollectors.toMap(e->e,
              Integer::valueOf,
              (a,b)->a); // just keep the first one

prints

5=5
7=7
8=8
9=9
温折酒 2025-01-25 11:02:49

任务№1作为键 - 字符串和值 - 字符频率


以获取每个字符的频率 ,您需要将 flatten 在列表中的每个字符串(IE分开 string targue )。

由于 java 9 我们可以使用方法

FlatMaptoint(String :: Chars)将产生intstream,其中包含来自给定列表中每个字符串的字符。

然后maptoobj()为每个流元素创建一个单字符串。

要生成频率地图,我们可以使用collector collector.groupingby()function.Identity()用作第一个参数等效于e-&gt; e,这只是一种说出流元素将用作而无需任何更改的方法。第二个参数是a downstream collector collector.counting(),它生成映射到特定的元素数。

public static Map<String, Long> getCharacterFrequency(List<String> list) {
    return list.stream()                               // Stream<String>
            .flatMapToInt(String::chars)               // IntStream
            .mapToObj(ch -> String.valueOf((char) ch)) // String<String>
            .collect(Collectors.groupingBy(Function.identity(),
                                           Collectors.counting()));
}

任务№2作为键 - 字符串和值 - 字符串转换为 integer

您可以使用 collector collector < /em> collectors.tomap()期望三个参数:

  • keymapper - 从流元素中产生 key 的函数;
  • valueMapper - 从流元素中产生 value 的函数;
  • MergeFunction - 确定如何解决两个值恰好映射到同一键时的情况的函数。

虽然,以下代码中的 MergeFunction 没有做任何特殊的事情,需要提供它,否则第一次遇到的重复将导致illegalstateException

public static Map<String, Integer> getStringValuesMappedToInts(List<String> list) {
    return list.stream()
            .collect(Collectors.toMap(Function.identity(), // key (String)
                                      Integer::valueOf,   // value (Integer)
                                      (v1, v2) -> v1));    // function that resolves collisions
}

main() - 演示

public static void main(String[] args) {
    List<String> source = List.of("5", "7", "57", "59", "5", "8", "99", "9", "8");
    // task 1
    System.out.println("task 1:\n" + getCharacterFrequency(source));
    // task 2
    System.out.println("task 2:\n" + getStringValuesMappedToInts(source));
}

输出

task 1:
{5=4, 7=2, 8=2, 9=4}
task 2:
{99=99, 57=57, 59=59, 5=5, 7=7, 8=8, 9=9}

task №1 as key - String, and value - character frequency

In order to obtain the frequency of every character, you need to flatten each string in a list (i.e. split every string into characters).

Since Java 9 we can use method chars() which returns a stream of characters represented with int primitives.

flatMapToInt(String::chars) will produce an IntStream, containing characters from every string in the given list.

Then mapToObj() creates a single-character string for every stream element.

To generate the map of frequencies, we can utilize collector Collectors.groupingBy(). Function.identity() is used as the first argument is an equivalent of e -> e, it's just a way to tell that stream elements will be used as a key without any changes. The second argument is a downstream collector Collectors.counting(), that generates the number of elements mapped to a particular key.

public static Map<String, Long> getCharacterFrequency(List<String> list) {
    return list.stream()                               // Stream<String>
            .flatMapToInt(String::chars)               // IntStream
            .mapToObj(ch -> String.valueOf((char) ch)) // String<String>
            .collect(Collectors.groupingBy(Function.identity(),
                                           Collectors.counting()));
}

task №2 as key - String, and value - string converted to integer

You can do it by using a flavor of collector Collectors.toMap() that expects three arguments:

  • keyMapper - a function that produces the key from a stream element;
  • valueMapper - a function that produces the value from a stream element;
  • mergeFunction - a function that determines how to resolve a situation when two values happens to be mapped to the same key.

Although, the mergeFunction in the code below is not doing anything special, it needs to be provided, otherwise the first encountered duplicate will cause an IllegalStateException.

public static Map<String, Integer> getStringValuesMappedToInts(List<String> list) {
    return list.stream()
            .collect(Collectors.toMap(Function.identity(), // key (String)
                                      Integer::valueOf,   // value (Integer)
                                      (v1, v2) -> v1));    // function that resolves collisions
}

main() - demo

public static void main(String[] args) {
    List<String> source = List.of("5", "7", "57", "59", "5", "8", "99", "9", "8");
    // task 1
    System.out.println("task 1:\n" + getCharacterFrequency(source));
    // task 2
    System.out.println("task 2:\n" + getStringValuesMappedToInts(source));
}

Output

task 1:
{5=4, 7=2, 8=2, 9=4}
task 2:
{99=99, 57=57, 59=59, 5=5, 7=7, 8=8, 9=9}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文