Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java集合对对象列表进行分组和计数_Java_Collections_Count_Grouping - Fatal编程技术网

使用Java集合对对象列表进行分组和计数

使用Java集合对对象列表进行分组和计数,java,collections,count,grouping,Java,Collections,Count,Grouping,哪个Java集合类更适合对对象列表进行分组 我有一个来自以下用户的消息列表: aaa hi bbb hello ccc Gm aaa Can? CCC yes ddd No 从这个消息对象列表中,我想计数并显示aaa(2)+bbb(1)+ccc(2)+ddd(1)。任何代码帮助?您可以使用Map,其中键表示单个字符串,Map值是每个字符串的计数器 因此,您可以执行以下操作: // where ever your input comes from: turn it into lower

哪个Java集合类更适合对对象列表进行分组

我有一个来自以下用户的消息列表:

aaa hi
bbb hello
ccc Gm
aaa  Can?
CCC   yes
ddd   No
从这个消息对象列表中,我想计数并显示
aaa(2)+bbb(1)+ccc(2)+ddd(1)
。任何代码帮助?

您可以使用
Map
,其中键表示单个字符串,Map值是每个字符串的计数器

因此,您可以执行以下操作:

// where ever your input comes from: turn it into lower case,
// so that "ccc" and "CCC" go for the same counter
String item = userinput.toLowerCase(); 

// as you want a sorted list of keys, you should use a TreeMap
Map<String, Integer> stringsWithCount = new TreeMap<>();
for (String item : str) {
  if (stringsWithCount.contains(item)) {
    stringsWithCount.put(item, stringsWithCount.get(item)+1));
  } else {
    stringsWithCount.put(item, 0);
  }
}
你需要番石榴汁。该集合类型是为此类任务量身定制的:

MultiSet<String> multiSet = new MultiSet<>();
for (String line : lines) { // somehow you read the lines
    multiSet.add(line.split(" ")[0].toLowerCase());
}
boolean first = true;
for (Multiset.Entry<String> entry : multiset.entrySet()) {
    if (!first) {
        System.out.println("+");
    }
    first = false;
    System.out.print(entry.getElement() + "(" + entry.getCount() + ")");            
}
MultiSet MultiSet=new MultiSet();
对于(stringline:lines){//您以某种方式阅读了这些行
multiSet.add(line.split(“”[0].toLowerCase());
}
布尔值优先=真;
for(Multiset.Entry:Multiset.entrySet()){
如果(!第一个){
System.out.println(“+”);
}
第一个=假;
System.out.print(entry.getElement()+“(“+entry.getCount()+”));
}

假设您使用Java 8,那么使用流API时可能会出现如下情况:

List<Message> messages = ...;
// Convert your list as a Stream
// Extract only the login from the Message Object
// Lowercase the login to be able to group ccc and CCC together
// Group by login using TreeMap::new as supplier to sort the result alphabetically
// Convert each entry into login(count)
// Join with a +
String result =
    messages.stream()
        .map(Message::getLogin)
        .map(String::toLowerCase)
        .collect(
            Collectors.groupingBy(
                Function.identity(), TreeMap::new, Collectors.counting()
            )
        )
        .entrySet()
        .stream()
        .map(entry -> entry.getKey() + '(' + entry.getValue() + ')')
        .collect(Collectors.joining("+"))
System.out.println(result);
如果您想按登录名对邮件进行分组,并将结果作为一个集合,则可以执行下一步:

Map<String, List<Message>> groupedMessages = 
    messages.stream()
        .collect(
            Collectors.groupingBy(
                message -> message.getLogin().toLowerCase(), 
                TreeMap::new, 
                Collectors.toList()
            )
        );
映射分组消息=
messages.stream()
.收集(
收集者分组(
message->message.getLogin().toLowerCase(),
树映射::新的,
收集者
)
);

将其他两个答案中的部分组合在一起,根据其他问题中的代码进行调整,并修复一些小错误:

    // as you want a sorted list of keys, you should use a TreeMap
    Map<String, Integer> stringsWithCount = new TreeMap<>();
    for (Message msg : convinfo.messages) {
        // where ever your input comes from: turn it into lower case,
        // so that "ccc" and "CCC" go for the same counter
        String item = msg.userName.toLowerCase();
        if (stringsWithCount.containsKey(item)) {
            stringsWithCount.put(item, stringsWithCount.get(item) + 1);
        } else {
            stringsWithCount.put(item, 1);
        }
    }
    String result = stringsWithCount
            .entrySet()
            .stream()
            .map(entry -> entry.getKey() + '(' + entry.getValue() + ')')
            .collect(Collectors.joining("+"));
    System.out.println(result);

HashMap
以前曾多次用于类似目的(假设您将
aaa
存储为字符串对象;否则您将希望使用字符串以外的其他类型作为键,只需确保该类型实现了
hashCode()
equals()
)。您好,谢谢您的回答,但没有解决我的问题。。。我有一个类似Hashset messages=newhashset()的列表;消息包含如上所述的用户nd消息列列表。所以我必须提取和显示用户的计数。您必须向我们展示一些代码,这将是描述您的设计的最精确的方式。最好为我们制作i。代码在这个链接中,那里有很多代码……提示:您应该更明确地说明,您的解决方案需要使用第三方库。我还想知道multiset是否会将“ccc”视为“ccc”——正如他在示例输入中给出的那样。也许他可以;但是这个问题不需要求助于第三方库就可以解决。很抱歉风格不一致。根据您的喜好和Java版本,您可以使用循环或流来完成所有操作。。。。但是我不能用流(Java7/8)特性来实现它。。。不知道为什么在eclipse中仍然会出现错误。。所以我用了老办法,像地图输入和遍历它的工作!如何从中得出最后的结果?呃,我相信这是个很难回答的问题。幸运的是,它非常简单,您可能很容易找到自己:
stringsWithCount
被声明为一个
TreeMap
TreeMap
SortedMap
接口的实现(这就是@GhostCar和@NicolasFilotto建议的原因)。在
SortedMap
的API文档中,您注意到九种方法之一是
lastKey()
。因此
stringsWithCount.lastKey()
将返回
“WVU”
。如果您将其传递到
stringsWithCount.get()
,您也将获得计数(即,在本例中为1)。我尝试了stringWithCount.lastKey()打印我,就像G_LO G_LO WVU WVU WVU WVU WVU WVU WVU WVU WVU
aaa(2)+bbb(1)+ccc(2)+ddd(1)
Map<String, List<Message>> groupedMessages = 
    messages.stream()
        .collect(
            Collectors.groupingBy(
                message -> message.getLogin().toLowerCase(), 
                TreeMap::new, 
                Collectors.toList()
            )
        );
    // as you want a sorted list of keys, you should use a TreeMap
    Map<String, Integer> stringsWithCount = new TreeMap<>();
    for (Message msg : convinfo.messages) {
        // where ever your input comes from: turn it into lower case,
        // so that "ccc" and "CCC" go for the same counter
        String item = msg.userName.toLowerCase();
        if (stringsWithCount.containsKey(item)) {
            stringsWithCount.put(item, stringsWithCount.get(item) + 1);
        } else {
            stringsWithCount.put(item, 1);
        }
    }
    String result = stringsWithCount
            .entrySet()
            .stream()
            .map(entry -> entry.getKey() + '(' + entry.getValue() + ')')
            .collect(Collectors.joining("+"));
    System.out.println(result);
aaa(2)+bbb(1)+ccc(2)+ddd(1)