我们什么时候使用AtomicReference?
是否需要在所有多线程程序中创建对象?
提供一个应该使用AtomicReference的简单示例.
我最近遇到了错误消息"空白的最终字段obj可能尚未初始化".
通常情况下,如果您尝试引用可能尚未分配给值的字段.示例类:
public class Foo {
private final Object obj;
public Foo() {
obj.toString(); // error (1)
obj = new Object();
obj.toString(); // just fine (2)
}
}
Run Code Online (Sandbox Code Playgroud)
我用Eclipse.在行中(1)我得到错误,在行中(2)一切正常.到目前为止这是有道理的.
接下来,我尝试obj在构造函数内创建的匿名接口中访问.
public class Foo {
private Object obj;
public Foo() {
Runnable run = new Runnable() {
public void run() {
obj.toString(); // works fine
}
};
obj = new Object();
obj.toString(); // works too
}
}
Run Code Online (Sandbox Code Playgroud)
这也有效,因为我obj在创建界面时无法访问.我也可以将我的实例传递给其他地方,然后初始化对象obj然后运行我的界面.(但null在使用之前检查是否合适). …
当我编写这段代码时,我得到一个编译时错误,上面写着: 'lambdas中的变量必须是最终的或有效的最终'.
现在,我得到这个从行中删除i:
futureLists.add(executorService.submit(() - >"Hello world"+ i));
解决了这个问题.
但我想知道为什么存在这样的要求?
根据JLS,它说的是:
使用但未在lambda表达式中声明的任何局部变量,形式参数或异常参数必须声明为final或有效final,否则在尝试使用时会发生编译时错误.
但它没有说明,为什么存在这样的要求.但是为什么Java工程师对lambdas强制执行这样的要求呢?
public class test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<Future<String>> futureLists = new ArrayList<>();
for (int i = 0; i < 20; i++) {
futureLists.add(executorService.submit( () -> "Hello world" + i));
}
for (Future<String> itr:futureLists) {
System.out.println(itr.get());
}
}
}
Run Code Online (Sandbox Code Playgroud) 给定两个对象列表,我将能够根据其中一个属性判断哪些项目不在其交叉点中.我们来看下面的例子:
我有一个Foo有两个属性的类:boo和placeholder
class Foo {
private int boo;
private int placeholder = 1;
public Foo(int boo) {
this.boo = boo;
}
public int getBoo() {
return boo;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我正在创建两个列表(让我们说这是我的输入)
List<Foo> list1 = new ArrayList<Foo>();
list1.add(new Foo(1));
list1.add(new Foo(2));
list1.add(new Foo(3));
List<Foo> list2 = new ArrayList<Foo>();
list2.add(new Foo(0));
list2.add(new Foo(1));
list2.add(new Foo(2));
Run Code Online (Sandbox Code Playgroud)
现在我想根据它们的属性说出哪些项目在list1,不在list2或list2不存在.所以在上面的例子中我想要一个包含一个和一个的例子.list1booList<Foo> notInIntersectListFoo(0)Foo(3)
List<Foo> notInIntersectList = new ArrayList<Foo>();
list1.forEach(li1foo -> {
boolean inBothLists …Run Code Online (Sandbox Code Playgroud) 这个问题已经被问到了。但今天我发现了一些奇怪的事情。对于以下代码:-
public static List<EsbBucketInstanceDefinition> convertBucketDefinitionList(List<BucketInstanceDefinitionV1> bucketInstanceDefinitionV1List) {
List<EsbBucketInstanceDefinition> response = new ArrayList<>();
List<EsbBucketInstanceDefinition> finalResponse = new ArrayList<>();
bucketInstanceDefinitionV1List.stream().forEach(e -> {
EsbBucketInstanceDefinition esbBucketInstanceDefinition = new EsbBucketInstanceDefinition();
esbBucketInstanceDefinition.setInstanceType(e.getInstanceType());
esbBucketInstanceDefinition.setReportingGroup(e.getReportingGroup());
esbBucketInstanceDefinition.setSliceVolume(e.getSliceVolume());
esbBucketInstanceDefinition.setCounterName(e.getCounterName());
esbBucketInstanceDefinition.setSubscriberGroupId(e.getSubscriberGroupId());
// response.add(esbBucketInstanceDefinition); compiler error variable used in lambda should be final or effective final
finalResponse.add(esbBucketInstanceDefinition);
});
return finalResponse;
}
Run Code Online (Sandbox Code Playgroud)
因为这个效果很好。看起来只有变量名 FinalResponse 有效。如何以及为何?这样做有效吗?
这个问题之前已经在这里被问过\n
\n我的问题为什么在这里得到回答\n
\n但是我对答案有一些疑问。\n提供的答案提到-
\n\n\n\n尽管其他答案证明了该要求,但它们没有解释该要求存在的原因。
\n
\n\nJLS 在\xc2\xa715.27.2中提到了原因:
\n
\n\n\n\n对有效最终变量的限制禁止访问动态更改的局部变量,捕获这些变量可能会引入并发问题。
\n
\n\n为了降低错误风险,他们决定确保捕获的变量永远不会发生变化。\n我对这会导致并发问题的说法感到困惑。\n
\n
我在Baeldung上阅读了有关并发问题的文章,但我仍然对它如何导致并发问题感到有点困惑,有人可以帮我举个例子吗。\n提前致谢。
\n我想在lambda函数中使用局部变量但我得到错误:请参阅代码中的1.和2.点.
class Foo {
int d = 0; // 1. It compiles, but ugly, 2. doesnt compile
public void findMax(List<List<Route>> routeLists) {
int d = 0; // 2.Error : Local variable dd defined in an enclosing scope must be final or effectively final
routeLists.forEach(e-> {
e.forEach(ee -> {
d+=ee.getDistance();
});
});
... doing some other operation with d
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能使用它们将它们设置为全局变量?
我正在研究Java 8流,我唯一的问题是了解lambda,这是为什么对于instance(和static)变量,lambdas中有效的最终警告会被忽略的原因。我似乎无法在网上找到任何提及它,因为大多数网页将刚才讲的是“有效决赛”的定义。
public class LambdaTest {
int instanceCounter = 0;
public void method() {
int localCounter = 0;
instanceCounter = 5; //Re-assign instance counter so it is no longer effectively final
Stream.of(1,2,3).forEach(elem -> instanceCounter++); //WHY DOES THE COMPILER NOT COMPLAIN HERE
Stream.of(1,2,3).forEach(elem -> localCounter++); //Does not compile because localCounter is not effectively final
}
}
Run Code Online (Sandbox Code Playgroud) 以下代码段无法编译.如何找到如下所示的sum使用forEach方法?
private int Sum(ArrayList<Integer> inputs) {
int sum = 0;
inputs.stream().forEach(x -> sum += x);
return sum;
}
Run Code Online (Sandbox Code Playgroud) 我无法理解为什么java语言的实现者使得lambda中使用的变量和从函数作用域传递的变量必须是最终的.
我反编译了这段代码:
public class Main {
@FunctionalInterface
interface Test {
void method(int t);
}
static void test(Test t) {
t.method(3);
}
public static void main(String... args) {
int a = 3;
test((i)-> {
System.out.println(a + i);
});
}
}
Run Code Online (Sandbox Code Playgroud)
而编译器所做的就是复制该变量,就好像它是通过构造函数传递一样.我得到了这三个班:
1:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import Main.1;
import Main.Test;
public class Main {
public Main() {
}
static void test(Test var0) {
var0.method(3);
}
public static …Run Code Online (Sandbox Code Playgroud) 我是 Java 流和函数式编程的新手,我想知道我的问题是否有一个有效的用例,或者它只是没有意义。我有以下代码,它从数组中提供了一个集合
public static void main(String[] args) {
String []arr = {"a","abc","b","cd"};
Set<String> dict = new HashSet<>();
Arrays.stream(arr).map(item->{
System.out.println(item);
dict.add(item);
return dict;
});
// dict = Arrays.stream(arr).collect(Collectors.toSet());
System.out.println(dict);
}
Run Code Online (Sandbox Code Playgroud)
这给了我一个空的字典。如果我按照倒数第二行的方式去做,它就会起作用。有没有一种方法可以改变已经实例化的dict流外部实例化的数据,使其填充到函数中map?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NewTest {
public static void main(String[] args) {
String mystr = "banana";
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < mystr.length(); i++) {
Runnable task = () -> {
System.out.print(mystr.charAt(i));
};
executor.submit(task);
}
executor.shutdown();
}
}
Run Code Online (Sandbox Code Playgroud) lambda表达式可以替代吗?使用当前的代码,我无法访问变量maxCnt,对其进行修改并发送回使用。
int maxCnt = 0;
incoming.stream().forEach(a -> {
Integer cnt = wordFrequency.get(a);
if (cnt != null) {
if (cnt > maxCnt) {
maxCnt = cnt;
}
}
});
Run Code Online (Sandbox Code Playgroud) java ×12
lambda ×7
java-8 ×6
java-stream ×5
concurrency ×1
constructor ×1
final ×1
for-loop ×1
jvm ×1
variables ×1