java map 元素个数_Java中List存储的Map数据根据元素的字段分类统计方法设计和实现...

本文通过示例展示了在Java中如何利用Map数据结构统计List<Map<String, String>>中元素的cmmdtyCode和supplierCode组合的出现次数。提供三种不同的实现方法:普通Map迭代增加、ConcurrentMap的putIfAbsent方法以及使用Google Guava的HashMultimap进行分组统计,对比了它们的性能和适用场景。" 106703800,8814872,使用Cypher在Neo4j中实现实时推荐,"['图数据库', 'Java', '大数据', '人工智能', '图形分析']
摘要由CSDN通过智能技术生成

业务场景:

有一批节点,每个节点的字段是是一样的,如下:uid,cmmdtyCode,supplierCode。要求统计各商户下各个cmmdtyCode出现了多少次。样例数据如下:

[

{

"uid":"127437864373237009",

"cmmdtyCode":" 000000000659869748",

"supplierCode":" 0070113914"

},

{

"uid":"127437864373237010",

"cmmdtyCode":" 000000000659869748",

"supplierCode": " 0070113914"

},

{

"uid":”127437864373237011”,

"cmmdtyCode":" 000000000659869749",

"supplierCode":" 0070113914"

},

{

"uid”:”127437864373237012”,

"cmmdtyCode":" 000000000659869748",

"supplierCode": "0070113915"

}

]

预期输出:supplierCode:cmmdtyCode=商品出现次数

实现方法

1)环境说明

本例jdk版本为1.7,代码在testng里面执行

2)数据准备

将前面的样例数据以List>的格式存储起来,代码如下:

import java.util.List;

import java.util.Map;

import org.powermock.modules.testng.PowerMockTestCase;

import org.testng.annotations.BeforeMethod;

import com.beust.jcommander.internal.Lists;

import com.google.common.collect.Maps;

public class TestJ2 extends PowerMockTestCase {

private List> params = Lists.newArrayList();

@BeforeMethod

public void initMethod() {

Map item = Maps.newHashMap();

item.put("uid", "127437864373237009");

item.put("cmmdtyCode", "000000000659869748");

item.put("supplierCode", "0070113914");

params.add(item);

Map item2 = Maps.newHashMap();

item2.put("uid", "127437864373237010");

item2.put("cmmdtyCode", "000000000659869748");

item2.put("supplierCode", "0070113914");

params.add(item2);

Map item3 = Maps.newHashMap();

item3.put("uid", "127437864373237011");

item3.put("cmmdtyCode", "000000000659869749");

item3.put("supplierCode", "0070113914");

params.add(item3);

Map item4 = Maps.newHashMap();

item4.put("uid", "127437864373237012");

item4.put("cmmdtyCode", "000000000659869748");

item4.put("supplierCode", "0070113915");

params.add(item4);

}

}

3)实现方法1

// 一般计算方法

@Test

public void execute() {

// 每个商户下,不同商品出现的次数

Map numMap = Maps.newHashMap();

for (Map item : params) {

Integer num = MapUtils.getInteger(numMap, getKey(item));

if (num == null) {

num = 1;

} else {

num += 1;

}

numMap.put(getKey(item), num);

}

printResult(numMap);

}

// 拼接业务主键

private String getKey(Map item) {

return MapUtils.getString(item, "supplierCode") + ":" + MapUtils.getString(item, "cmmdtyCode");

}

// 打印计算结果

private void printResult(Map numMap) {

for (Map.Entry entry : numMap.entrySet()) {

System.out.println(entry.getKey() + "=" + entry.getValue());

}

}

输出结果:

0070113914:000000000659869748=2

0070113914:000000000659869749=1

0070113915:000000000659869748=1

耗时:8ms

4)实现方法2

// 改进计算方法

/**

* 在jdk1.7(含)以下的版本中,普通Map类没有putIfAbsent,只有ConcurrentMap的子类才有,jdk8(含)之后,普通类也提供了该方法

* 由于作者本人机器使用的是JDK1.7,故使用ConcurrentMap类进行演示,实际上,在单线程计算中,普通map类的效率要高于ConcurrentMap

*/

@Test

public void execute2() {

ConcurrentMap numMap = Maps.newConcurrentMap();

for (Map item : params) {

// 如果集合中不包括key,则写入默认值1,并返回null;否则直接返回集合中key对应的value对象的引用

AtomicInteger oldValue = numMap.putIfAbsent(getKey(item), new AtomicInteger(1));

if (oldValue != null) {

// 对象数值+1

oldValue.incrementAndGet();// 利用map存储的是对象的引用,直接对象的值,不需要重新写回map

}

}

printResult(numMap);

}

// 拼接业务主键

private String getKey(Map item) {

return MapUtils.getString(item, "supplierCode") + ":" + MapUtils.getString(item, "cmmdtyCode");

}

private void printResult(Map numMap) {

for (Map.Entry entry : numMap.entrySet()) {

System.out.println(entry.getKey() + "=" + entry.getValue());

}

}

输出结果:

0070113914:000000000659869749=1

0070113914:000000000659869748=2

0070113915:000000000659869748=1

耗时:11ms

5)实现方法3

// 分组计算方法

@Test

public void execute3() {

HashMultimap> group = HashMultimap.create();

// 将所有节点分组,cmmdtyCode和supplierCode相同的item分入一组

for (Map item : params) {

group.put(getKey(item), item);

}

Map numMap = Maps.newHashMap();

// 统计每一组的元素个数

for (String key : group.keySet()) {

numMap.put(key, group.get(key).size());

}

printResult(numMap);

}

// 拼接业务主键

private String getKey(Map item) {

return MapUtils.getString(item, "supplierCode") + ":" + MapUtils.getString(item, "cmmdtyCode");

}

// 打印计算结果

private void printResult(Map numMap) {

for (Map.Entry entry : numMap.entrySet()) {

System.out.println(entry.getKey() + "=" + entry.getValue());

}

}

该方法引入了google API,具体引用路径为:

import com.google.common.collect.HashMultimap;

输出结果:

0070113914:000000000659869748=2

0070113914:000000000659869749=1

0070113915:000000000659869748=1

耗时:43ms

6)增加测试数据

@BeforeMethod

public void initMethod() {

for (int i = 0; i < 100; i++) {

Map itemR = Maps.newHashMap();

itemR.put("uid", i);

itemR.put("cmmdtyCode", "000000000659869748");

itemR.put("supplierCode", "0070113915");

params.add(itemR);

}

for (int j = 0; j < 100; j++) {

Map itemR = Maps.newHashMap();

itemR.put("uid", j);

itemR.put("cmmdtyCode", "000000000659869749");

itemR.put("supplierCode", "0070113915");

params.add(itemR);

}

for (int j = 0; j < 100; j++) {

Map itemR = Maps.newHashMap();

itemR.put("uid", j);

itemR.put("cmmdtyCode", "000000000659869748");

itemR.put("supplierCode", "0070113914");

params.add(itemR);

}

}

耗时如下:

数据量

10

100

1000

方法1耗时

11ms

8ms

19ms

方法2耗时

9ms

11ms

18ms

方法3耗时

45ms

40ms

59ms

总结:

方法1耗时最少,且较为常见,推荐

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值