[Java]-Java中集合定义初始化与Map使用

在《Java集合Collection简介及List与Map使用示例》我们介绍了集合的基本使用。本节介绍如何在定义时就初始化集合。

Collection

有时,需要集合在定义时就要初始化(特别是定义集合常量时)。

传统方式

Collection有两种常用的初始化方式:

  • 构造器方式:通过接受另外一个Collection来初始化集合;
  • add方式:静态变量可通过static块;
private static final Map<String, Integer> mapTest = new HashMap<>();
static {
    mapTest.add("one", 1);
    mapTest.add("two", 2);
}

双括号方式

双大括号初始化(double brace initialization)或者匿名内部类初始化法:第一层括号定义了一个内部匿名类(实际类型的子类);第二次括号则为匿名类实例的初始化代码。

List<Integer> lstTest = Arrays.asList(1, 3, 5, 7);
// 通过构造器初始化
Collection<Integer> colTest = new HashSet<>(lstTest);

// 通过add方法初始化
Set<Integer> setTest = new HashSet<Integer>() {
    {
        addAll(lstTest);
        add(2);
        add(4);
    }
};

利用双大括号初始化集合使代码简洁,但是也存在一些问题:

  • 从效率上来说可能不如标准的集合初始化步骤:原因在于使用双大括号初始化会导致内部类文件的产生,而这个过程就会影响代码的执行效率。
  • 串行化时可能存在问题:

Arrays.asList

List除通过上述方式外,也可通过Arrays.asList方便地通过把数字转换为List(此方式生成的List是不可修改的)。

List<Integer> lstTest = Arrays.asList(1, 3, 5, 7);

要生成ArrayList,可通过Guava中的Lists.newArrayList、或Stream.of来生成:

List<Integer> lstOne = Lists.newArrayList(1, 2, 3); // ArrayList
List<Integer> lstTwo = Stream.of(1, 2, 3).collect(Collectors.toList()); // ArrayList
List<Integer> lstThree = Arrays.asList(1, 2, 3);  // Arrays$ArrayList

Map

初始化示例

以一个value为BiFunction为例说明:当内部由Lambd表达式时,HashMap必须指明类型(否则可以直接用<>,让编译器自动推导)。

static{
    BiFunction<String, String, String> funOne = (n, p) -> {
        return checkNameOne(n, p);
    };
    Map<Integer, BiFunction<String, String, String>> mapFun = new HashMap<Integer, BiFunction<String, String, String>>() {{
        put(1, funOne);
        put(2, (n, p) -> checkNameTwo(n, p));
    }};
}

static String checkNameOne(String name, String phone) {
    return "One";
}

static String checkNameTwo(String name, String phone) {
    return "Two";
}

Stream流

Map中有三类流:键、值与键值对流;

Map<String, Integer> mapTest = new HashMap<String, Integer>() {{
    put("one", 1);
    put("two", 2);
    put("three", 3);
}};
mapTest.values().stream()
        .collect(Collectors.toSet());
mapTest.keySet().stream()
        .count();
mapTest.entrySet().stream()
        .forEach((e) -> System.out.println(e.getKey() + "=" + e.getValue()));

compute

map中可通过compute类函数方便地处理键值:通过接受一个BiFunction参数(参数为原来的key与value,返回新的value),可以对已有与新的value进行计算操作:

  • compute:键不存在时,value为null;
  • computeIfAbsent:键不存在时有效(参数为Function);
  • computeIfPresent:键存在时有效;
Map<String, Integer> mapCount = new HashMap<>();
for (int i = 0; i < 10; ++i) {
    Integer rand = RandomHelper.randInt(10);
    mapCount.compute(rand.toString(), (k, v) ->
            v == null ? rand : rand + v
    );
}

merge

merge与compute类似,但是其BiFunction参数为新、旧Value;

Map<String, Integer> mapCount = new HashMap<>();
for (int i = 0; i < 20; ++i) {
//   Integer rand = RandomHelper.randInt(10);
//     mapCount.compute(rand.toString(), (k, v) ->
//             v == null ? rand : rand + v
//     );
    mapCount.merge(rand.toString(), rand, (oldV, newV) ->
            oldV == null ? newV : oldV + newV
    );
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值