有没有办法forEach
在Java 8中构建一个使用索引进行迭代的方法?理想情况下,我喜欢这样的事情:
params.forEach((idx, e) -> query.bind(idx, e));
Run Code Online (Sandbox Code Playgroud)
我现在能做的最好的事情是:
int idx = 0;
params.forEach(e -> {
query.bind(idx, e);
idx++;
});
Run Code Online (Sandbox Code Playgroud) 如果lambda函数中有一个语句,我们可以省略为它定义完整的代码块:
new Thread(() -> System.out.println());
Run Code Online (Sandbox Code Playgroud)
为什么抛出异常的语句不是这种情况?这会产生一个编译错误,说明'{' expected
:
new Thread(() -> throw new RuntimeException());
Run Code Online (Sandbox Code Playgroud)
当然,将lambda主体封装在代码块中可以:
new Thread(() -> {
throw new RuntimeException();
});
Run Code Online (Sandbox Code Playgroud) 用于演示目的的简单类:
public class Main {
private static int counter = 0;
public static void main(String[] args) {
try {
f();
} catch (StackOverflowError e) {
System.out.println(counter);
}
}
private static void f() {
counter++;
f();
}
}
Run Code Online (Sandbox Code Playgroud)
我执行了5次上面的程序,结果是:
22025
22117
15234
21993
21430
Run Code Online (Sandbox Code Playgroud)
为什么结果每次都不同?
我尝试设置最大堆栈大小(例如-Xss256k
).然后结果更加一致,但每次都不相等.
Java版本:
java version "1.8.0_72"
Java(TM) SE Runtime Environment (build 1.8.0_72-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.72-b15, mixed mode)
Run Code Online (Sandbox Code Playgroud)
编辑
当JIT被禁用时(-Djava.compiler=NONE
)我总是得到相同的数字(11907
).
这是有道理的,因为JIT优化可能会影响堆栈帧的大小,并且JIT完成的工作肯定必须在执行之间变化.
尽管如此,我认为如果通过参考关于该主题的一些文档和/或JIT在这个特定示例中完成的工作的具体示例来确认该理论将导致框架大小改变将是有益的.
我正在使用buildnumber-maven-plugin将Mercurial变更集作为项目内部版本号:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>hgchangeset</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
然后我使用${changeSet}
property来设置build.number
属性pom.xml
:
<build.number>${changeSet}</build.number>
Run Code Online (Sandbox Code Playgroud)
但是,IntelliJ IDEA抱怨它Cannot resolve symbol 'changeSet'
:
此外,模块根目录和受影响的pom.xml
文件在"项目"工具窗口中以红色下划线.
我在设置中尝试了所有提供的Alt+Enter选项和Maven配置; 没什么帮助.
一切都建立和工作正常,我只是想摆脱IDE中显示的恼人的错误.有什么建议吗?
IDE和环境:
IntelliJ IDEA 2016.1.2
Build #IC-145.972, built on May 14, 2016
JRE: 1.8.0_65-b17 amd64
JVM: Java HotSpot(TM) 64-Bit Server VM by Oracle Corporation
Run Code Online (Sandbox Code Playgroud) 假设我们有一个参与XA事务的数据库(例如Oracle)和JMS提供者(例如HornetQ).消息被发送到JMS队列,并且一些数据在同一分布式事务中保留在数据库中.提交事务后,消息使用者将读取持久数据并在单独的事务中处理它们.
关于第一个XA事务,事务管理器可以执行以下事件序列(例如JBoss)
如果消息使用者在HornetQ中完成提交后开始读取数据,但仍在Oracle中执行,会发生什么?消息使用者是否会读取陈旧数据?
这个问题可以推广到参与XA事务的任何类型的多个资源,即是否有可能存在一个小的时间窗口(当执行提交阶段时),其中来自另一个并发事务的读者可以获得不一致的状态(通过读取提交一个资源的数据和另一个资源的陈旧数据)?
我想说,事务资源阻止这种情况的唯一方法是在准备阶段完成后阻止受影响数据的所有读者,直到发布提交.这样,上面提到的示例消息使用者将阻塞,直到数据在数据库中提交.
AtomicInteger
使用两个概念:CAS和volatile
变量.
使用volatile
变量确保当前值对所有线程可见,并且不会被缓存.
但我对CAS(比较和设置)概念感到困惑,其解释如下:
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是什么if(compareAndSet(current, next)
回归false
?价值会不会更新?在这种情况下,当Thread执行以下情况时会发生什么:
private AtomicInteger count = new AtomicInteger();
count.incrementAndGet();
Run Code Online (Sandbox Code Playgroud) 为了简化我的实际用例,我们假设我想在列表中找到最大数量:
var max : Int? = null
listOf(1, 2, 3).forEach {
if (max == null || it > max) {
max = it
}
}
Run Code Online (Sandbox Code Playgroud)
但是,编译失败,并出现以下错误:
智能转换为'Int'是不可能的,因为'max'是一个由变化的闭包捕获的局部变量
为什么更改闭包会阻止智能演员在此示例中工作?
我是编程新手,我正在学习Java.我只是想知道为什么我应该在只有一个实现类时使用接口?
通常需要为以下查询转换结果:
select category, count(*)
from table
group by category
Run Code Online (Sandbox Code Playgroud)
到一个映射,其中键是类别,值是属于同一类别的记录的数量.
许多持久性框架返回此类查询的结果List<Object[]>
,其中对象数组包含两个元素(类别和每个返回结果集行的计数).
我试图找到最可读的方式将此列表转换为相应的地图.
当然,传统方法包括创建地图并手动输入条目:
Map<String, Integer> map = new HashMap<>();
list.stream().forEach(e -> map.put((String) e[0], (Integer) e[1]));
Run Code Online (Sandbox Code Playgroud)
我想到的第一个单线程是利用开箱即用的Collectors.toMap
收集器:
Map<String, Integer> map = list.stream().collect(toMap(e -> (String) e[0], e -> (Integer) e[1]));
Run Code Online (Sandbox Code Playgroud)
但是,我发现这种e -> (T) e[i]
语法比传统方法的可读性差一点.为了解决这个问题,我可以创建一个util方法,我可以在所有这些情况下重用它:
public static <K, V> Collector<Object[], ?, Map<K, V>> toMap() {
return Collectors.toMap(e -> (K) e[0], e -> (V) e[1]);
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个完美的单行:
Map<String, Integer> map = list.stream().collect(Utils.toMap());
Run Code Online (Sandbox Code Playgroud)
由于类型推断,甚至不需要转换键和值.但是,对于代码的其他读者(Collector<Object[], ?, Map<K, V>>
在util方法签名等中)来说,这有点难以理解. …
假设我们有一个标准的流操作方法链:
Arrays.asList("a", "bc", "def").stream()
.filter(e -> e.length() != 2)
.map(e -> e.length())
.forEach(e -> System.out.println(e));
Run Code Online (Sandbox Code Playgroud)
JLS中是否有关于流操作应用于列表元素的顺序的保证?
例如,是否保证:
"bc"
之前,不会发生应用过滤谓词"a"
?"def"
之前,应用映射函数是不会发生的"a"
?1
将在之前打印3
?注意:我在这里专门讨论stream()
,而不是 parallelStream()
预期映射和过滤等操作并行完成的地方.