任何人都可以指向官方Java文档,该文档描述了Stream将为每个元素调用每个"非干扰和无状态"中间操作的次数.
例如:
Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));
public boolean check(Object o) {
return true;
}
Run Code Online (Sandbox Code Playgroud)
以上目前将调用check
方法4次.
是否有可能在JDK的当前版本或未来版本中,该check
方法的执行次数多于或少于从List或任何其他标准Java API创建的流中的元素数量?
似乎这个问题应该已经有了答案,但我找不到重复的答案。
无论如何,我想知道社区对这样的Stream.map
用例有何看法?
Wrapper wrapper = new Wrapper();
list.stream()
.map( s -> {
wrapper.setSource(s);
return wrapper;
} )
.forEach( w -> processWrapper(w) );
public static class Source {
private final String name;
public Source(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public static class Wrapper {
private Source source = null;
public void setSource(Source source) {
this.source = source;
}
public String getName() {
return source.getName();
}
}
public void processWrapper(Wrapper wrapper) …
Run Code Online (Sandbox Code Playgroud) 我正在研究一个项目,我们是批量加载并在Oracle数据库中存储大量数据,这些数据经常通过Hibernate对这个1亿多个记录表进行查询(读取比写入更频繁).为了加快速度,我们使用Lucene进行一些查询(尤其是地理边界框查询)和Hibernate二级缓存,但这仍然不够.我们仍然遇到针对Oracle的Hibernate查询的瓶颈(由于缺少那么多内存,我们不会在Hibernate二级缓存中缓存超过1亿个表实体).
在这种情况下我可以利用哪些额外的NoSQL解决方案(除了Lucene)?
我想到的一些选择是:
使用分布式ehcache(Terracotta)用于Hibernate二级,以跨机器利用更多内存并减少重复缓存(现在每个VM都有自己的缓存).
要在内存中完全使用像H2这样的SQL数据库,但不幸的是,这些解决方案需要将100多万个表加载到单个VM中.
使用Lucene进行查询,使用BigTable(或分布式hashmap)进行实体查找.什么BigTable实现适合这个?我在考虑HBase.
使用MongoDB存储数据以及通过id查询和查找.
我一直试图从官方Java文档中找到明确的合同,关于Java流的顺序,一旦调用终端操作,就处理元素并调用中间操作.
例如,让我们看看这些使用Java流版本和普通迭代版本的示例(两者都产生相同的结果).
例1:
List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5);
Function<Integer, Integer> map1 = i -> i;
Predicate<Integer> f1 = i -> i > 2;
public int findFirstUsingStreams(List<Integer> ints){
return ints.stream().map(map1).filter(f1).findFirst().orElse(-1);
}
public int findFirstUsingLoopV1(List<Integer> ints){
for (int i : ints){
int mappedI = map1.apply(i);
if ( f1.test(mappedI) ) return mappedI;
}
return -1;
}
public int findFirstUsingLoopV2(List<Integer> ints){
List<Integer> mappedInts = new ArrayList<>( ints.size() );
for (int i : ints){
int mappedI = map1.apply(i);
mappedInts.add(mappedI);
} …
Run Code Online (Sandbox Code Playgroud) 我想看到的描述多少次的行为实际Java文档mappingFunction
传递到时可以调用 ConcurrentHashMap.computeIfAbsent
和ConcurrentHashMap.computeIfPresent
方法.
Javadoc ConcurrentHashMap.computeIfAbsent
似乎很清楚地表示mappingFunction
将最多执行一次:
Javadoc for ConcurrentHashMap.computeIfAbsent
如果指定的键尚未与值关联,则尝试使用给定的映射函数计算其值,并将其输入此映射,除非为null.整个方法调用是以原子方式执行的,因此每个键最多应用一次该函数.其他线程在此映射上的某些尝试更新操作可能在计算进行时被阻止,因此计算应该简短,并且不得尝试更新此映射的任何其他映射.
但Javadoc for ConcurrentHashMap.computeIfPresent
没有说明mappingFunction
可以执行多少次:
Javadoc for ConcurrentHashMap.computeIfPresent
如果存在指定键的值,则尝试在给定键及其当前映射值的情况下计算新映射.整个方法调用以原子方式执行.其他线程在此映射上的某些尝试更新操作可能在计算进行时被阻止,因此计算应该简短,并且不得尝试更新此映射的任何其他映射.
通过查看源代码,它们看起来mappingFunction
最多只能执行一次.但我真的希望看到保证这种行为的实际文档.
有这样的文件吗?
当已经运行的任务之一抛出异常时,我需要取消所有已调度但尚未运行的CompletableFuture任务.
尝试以下示例,但大多数情况下main方法不会退出(可能是由于某种类型的死锁).
public static void main(String[] args) {
ExecutorService executionService = Executors.newFixedThreadPool(5);
Set< CompletableFuture<?> > tasks = new HashSet<>();
for (int i = 0; i < 1000; i++) {
final int id = i;
CompletableFuture<?> c = CompletableFuture
.runAsync( () -> {
System.out.println("Running: " + id);
if ( id == 400 ) throw new RuntimeException("Exception from: " + id);
}, executionService )
.whenComplete( (v, ex) -> {
if ( ex != null ) {
System.out.println("Shutting down.");
executionService.shutdownNow();
System.out.println("shutdown.");
}
} …
Run Code Online (Sandbox Code Playgroud) java ×5
java-8 ×5
java-stream ×3
hbase ×1
hibernate ×1
java-threads ×1
mongodb ×1
nosql ×1
terracotta ×1