java 基本功

Java8新特性10--其他类库的变化

2017-06-13  本文已影响511人  不迷失
21e610bd65f6d2693ec165b05927730b

Map

 public static void main(String[] arg) {
        Map map=new HashMap();
        //如果key不存在返回默认值
        System.out.println(map.getOrDefault("a",123));


        map.put("a",123);

        //将lambda结果放入该key
        map.compute("a",(key,value)-> key+""+value );

        System.out.println(map.get("a"));//a123

        //如果key不存在,则将lambda结果放入该key
        map.computeIfAbsent("a",(key)-> key+"234" );

        //如果key存在,则将lambda结果更新该key,如果lambda结果返回null,则移除该key
        map.computeIfPresent("a",(key,value)-> key+"kv"+value);//->akva123

        //如果key对应的值为null则用新value更新,否则用lambda结果更新,如果lambda的值为null,则移除此key
        //lambda表达式中参数oldvalue是原key对应的value,newvalue是第二个参数指定的值
        map.merge("a","newvalue",(oldvalue,newvalue)-> oldvalue+"dv"+newvalue);//->akva123dv

        //如果key不存在,则将值放入此key
        map.putIfAbsent("b","b123");

        //当key存在并且key对应的value等于新的值时,移除此key
        map.remove("b","b124");

        //如果存在key,则替换key的值
        map.replace("b","b125");

        //遍历
        map.forEach((key,value)->System.out.println("key:"+key+";value:"+value));
        
    }

运行结果:

123
a123
key:a;value:akva123dvnewvalue
key:b;value:b125

集合

removeIf 方法可以移除集合中满足某个谓词的所有元素。注意,这一方法与Stream API时提到的 filter 方法不大一样。Stream API中的 filter 方法会产生一个新的流,不会对当前作为数据源的流做任何变更。

列表

replaceAll 方法会对列表中的每一个元素执行特定的操作,并用处理的结果替换该元素。它的功能和Stream中的 map 方法非常相似,不过 replaceAll 会修改列表中的元素。与此相反,map 方法会生成新的元素。

比如,下面这段代码会打印输出[2,4,6,8,10],因为列表中的元素被原地修改了:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.replaceAll(x -> x * 2);
System.out.println(numbers);

Comparator

Comparator 接口现在同时包含了默认方法和静态方法。

新的实例方法包含了下面这些。

新的静态方法包括下面这些。

并发

java.util.concurrent.atomic 包提供了多个对数字类型进行操作的类,比如 Atomic-
Integer 和 AtomicLong ,它们支持对单一变量的原子操作。这些类在Java 8中新增了更多的方
法支持。

Adder 和 Accumulator
多线程的环境中,如果多个线程需要频繁地进行更新操作,且很少有读取的动作,Java API文档中推荐大家使用新的类 LongAdder 、 LongAccumulator 、DoubleAdder 以及DoubleAccumulator ,尽量避免使用它们对应的原子类型。这些新的类在设计之初就考虑了动态增长的需求,可以有效地减少线程间的竞争。

LongAddr 和 DoubleAdder 类都支持加法操作,而 LongAccumulator 和 DoubleAccu-
mulator 可以使用给定的方法整合多个值。比如,可以像下面这样使用 LongAdder 计算多个值的总和。

  public static void main(String[] arg) throws InterruptedException {
        LongAdder longAdder=new LongAdder();//初始值为0
        longAdder.add(1);//加1
        longAdder.add(2);
        System.out.println(longAdder.sum());//得到总和 3

        //使用lambda表达式积累值,初始值是0,a是lambda计算后的值,b是每次累积的值
        LongAccumulator longAccumulator=new LongAccumulator((a,b)->{
            System.out.println("a:"+a+";b:"+b);
            return a+b;//累加
        },0);
        //可以安全用于多线程环境
        for(int i=1;i<=10;i++){
            new Thread(()->longAdder.add(1)).start();//每次加1
            new Thread(()->longAccumulator.accumulate(2)).start();//每次传个2过去
        }
        Thread.sleep(2000);
        System.out.println(longAdder.sum());//13
        System.out.println(longAccumulator.get());//20

    }

运行结果:

3
a:0;b:2
a:2;b:2
a:4;b:2
a:6;b:2
a:8;b:2
a:10;b:2
a:12;b:2
a:14;b:2
a:16;b:2
a:18;b:2
13
20

ConcurrentHashMap

ConcurrentHashMap 支持三种新的操作,这些操作和你之前在流中所见的很像:

以上每一种操作都支持四种形式,接受使用键、值、 Map.Entry 以及键值对的函数:

注意,这些操作不会对 ConcurrentHashMap 的状态上锁。它们只会在运行过程中对元素进行操作。应用到这些操作上的函数不应该对任何的顺序,或者其他对象,抑或在计算过程发生变化的值,有依赖。

除此之外,你需要为这些操作指定一个并发阈值。如果经过预估当前 map 的大小小于设定的阈值,操作会顺序执行。使用值 1 开启基于通用线程池的最大并行。使用值 Long.MAX_VALUE 设定程序以单线程执行操作。

下面这个例子中,我们使用 reduceValues 试图找出 map 中的最大值:

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
Optional<Integer> maxValue = Optional.of(map.reduceValues(1, Integer::max));

ConcurrentHashMap 类还提供了一个新的方法,名叫 mappingCount ,它以长整型 long 返回map 中映射的数目。我们应该尽量使用这个新方法,而不是老的 size 方法, size 方法返回的类型为 int 。这是因为映射的数量可能是 int 无法表示的。

ConcurrentHashMap 类还提供了一个名为 KeySet 的新方法,该方法以 Set 的形式返回ConcurrentHashMap 的一个视图(对 map 的修改会反映在该 Set 中,反之亦然)。你也可以使用新的静态方法 newKeySet ,由 ConcurrentHashMap 创建一个 Set 。

Number

Java 8 API对 Number 和 Math 也做了改进,为它们增加了新的方法。
Number 类中新增的方法如下:

Math

如果 Math 中的方法在操作中出现溢出, Math 类提供了新的方法可以抛出算术异常。支持这一异常的方法包括使用 int 和 long 参数的 addExact 、 subtractExact 、 multipleExact 、incrementExact 、 decrementExact 和 negateExact 。此外, Math 类还新增了一个静态方法toIntExact ,可以将 long 值转换为 int 值。其他的新增内容包括静态方法 floorMod 、 floorDiv和 nextDown 。

Files

Files 类最引人注目的改变是,你现在可以用文件直接产生流。新的静态方法 Files.lines ,通过该方法你可以以延迟方式读取文件的内容,并将其作为一个流。此外,还有一些非常有用的静态方法可以返回流。

String

String 类也新增了一个静态方法,名叫 join 。它可以用一个分隔符将多个字符串连接起来。你可以像下面这样使用它:
String authors = String.join("," , "Raoul", "Mario", "Alan");

@不迷失|知识改善生活

微信公众号:java技术

1492957339
专注技术研究与视频教学,分享有价值的技术与经验,关注程序员的发展!

技术博客:http://bumishi.cn

技术交流群:245130488

@不迷失教学视频

xiaoetong_qrcode qqketang_qrcode
腾讯课堂:http://bumishi.ke.qq.com baiduketang_qrcode
百度课堂:http://chuanke.com/s3377987.html
上一篇 下一篇

猜你喜欢

热点阅读