我在这里发布了一个答案,其中演示使用< code>ConcurrentMap的< code>putIfAbsent方法的代码如下:
ConcurrentMap<String, AtomicLong> map = new ConcurrentHashMap<String, AtomicLong> ();
public long addTo(String key, long value) {
// The final value it became.
long result = value;
// Make a new one to put in the map.
AtomicLong newValue = new AtomicLong(value);
// Insert my new one or get me the old one.
AtomicLong oldValue = map.putIfAbsent(key, newValue);
// Was it already there? Note the deliberate use of '!='.
if ( oldValue != newValue ) {
// Update it.
result = oldValue.addAndGet(value);
}
return result;
}
这种方法的主要缺点是您必须创建一个新对象来放入地图中,无论它是否会被使用。如果对象很重,这可能会产生重大影响。
我想到这将是一个使用Lambdas的机会。我还没有下载Java 8 n,或者在它成为官方(公司政策)之前我可以下载,所以我无法测试它,但这样的东西是否有效?
public long addTo(String key, long value) {
return map.putIfAbsent( key, () -> new AtomicLong(0) ).addAndGet(value);
}
我希望使用lambda来延迟对新AtomicLong(0)
的求值,直到它实际确定应该创建它,因为它不存在于映射中。
如您所见,这更加简洁和实用。
基本上我想我的问题是:
不幸的是,这并没有那么容易。您概述的方法有两个主要问题:1.地图的类型需要从Map更改
然而,有一个按需运行函数来填充缺失值的地图的想法是一个很好的想法,事实上谷歌的番石榴库有一个地图可以做到这一点;参见他们的MapMaker。事实上,代码将受益于Java8个lambda表达式:而不是
ConcurrentMap<Key, Graph> graphs = new MapMaker()
.concurrencyLevel(4)
.weakKeys()
.makeComputingMap(
new Function<Key, Graph>() {
public Graph apply(Key key) {
return createExpensiveGraph(key);
}
});
你就可以写字了
ConcurrentMap<Key, Graph> graphs = new MapMaker()
.concurrencyLevel(4)
.weakKeys()
.makeComputingMap((Key key) -> createExpensiveGraph(key));
或
ConcurrentMap<Key, Graph> graphs = new MapMaker()
.concurrencyLevel(4)
.weakKeys()
.makeComputingMap(this::createExpensiveGraph);
AtomicLong
实际上不是一个沉重的对象。对于较重的对象,我会考虑使用惰性代理,并在需要时向该代理提供lambda以创建对象。
class MyObject{
void doSomething(){}
}
class MyLazyObject extends MyObject{
Funktion create;
MyLazyObject(Funktion create){
this.create = create;
}
MyObject instance;
MyObject getInstance(){
if(instance == null)
instance = create.apply();
return instance;
}
@Override void doSomething(){getInstance().doSomething();}
}
public long addTo(String key, long value) {
return map.putIfAbsent( key, new MyLazyObject( () -> new MyObject(0) ) );
}
更新 2015-08-01
下面描述的< code > computeifaxine 方法确实已经添加到Java SE 8中。语义似乎非常接近预发布版本。
此外,computeIfAbsent
以及一大堆新的默认方法已添加到 Map
接口中。当然,地图通常不支持原子更新,但新方法为 API 增加了相当大的便利性。
您尝试的做法非常合理,但不幸的是,它不适用于当前版本的< code>ConcurrentMap。然而,一项改进正在进行中。新版本的并发库包括< code>ConcurrentHashMapV8,其中包含一个新方法< code > computeifaxine 。这几乎可以让你做你想做的事情。使用这种新方法,您的示例可以重写如下:
public long addTo(String key, long value) {
return map.computeIfAbsent( key, () -> new AtomicLong(0) ).addAndGet(value);
}
有关ConcurrentHashMapV8
的更多信息,请参阅DougLea在并发兴趣邮件列表上的初始公告线程。线程下面的几个消息是一个后续消息,它显示了一个与您所尝试的非常相似的示例。(不过,请注意旧的lambda语法。该消息毕竟来自2011年8月。)这里是最近的javadoc for<code>ConcurrentHashMapV8</code>。
这项工作打算集成到Java 8中,但据我所知,它还没有。此外,这仍在进行中,名称和规格可能会更改等。
我在Java8中遇到了一个问题,在使用cast时,它不允许我收集对象。 我得到了编译器错误: 错误:(71,23)java:不兼容类型:推理变量T的边界不兼容等式约束:java。util。列出下限:java。lang.反对 任何帮助都将不胜感激。 更新:
温馨提示:该项目已开源,用户在项目基础上的所有操作、修改须进行标记,并保留原项目版权说明。 羊驼!羊驼!前方惊现羊驼 ! 羊驼! 是一个开源的轻量级树状 CMS 系统。它基于 php + mysql 开发,并使用 b2core 为底层MVC架构。 可以方便快速的配置出个人、企业网站。 如果你是打算开发一个内容网站,或者是开发一款基于PHP的应用,羊驼!CMS 都会是个不错的开始,它可以帮你节省构
我有三个活动,每个都有一个按钮。Act1与btn1,Act2与btn2,Act3与btn3。我有另一个活动作为主活动,有三个图像视图:ImageView1、imageView2和imageView3,所有这些最初都是不可见的。我希望这样,当我在act1中单击btn1时,MainActivity中的imageView1将可见,而当再次单击btn1,ImageView 1将再次不可见。与imageVi
引用脚本的内容: ; 该脚本使用 HM VNISEdit 脚本编辑器向导产生 !include "LogicLib.nsh" ; 安装程序初始定义常量 !define PRODUCT_NAME "猪猪番薯主题包" !define PRODUCT_VERSION "1.3" !define PRODUCT_PUBLISHER "猪猪番薯论坛" !define PRODUCT_UNINST_KE
嗨,我是Hadoop的新手,我发现在Java map reduce中使用SkipBadRecord类可以跳过任何输入格式的badrecords,所以我只想知道在Pig和Hive中是如何实现的?