我需要编写一个Lambda函数,该函数可以自动递增计数器值。 例如-我的计数器值是0。然后,我执行lambda表达式,它将计数器值增加到1,将值1设置为counter并从lambda表达式返回此计数器值(1)。然后,下一次,当我调用lambda expression时,lambda应该将计数器值增加到2,并从lambda返回值(2)。怎么写这样的lambda。我是lambda编程的新手。如果我有一个非常简单直接的问题,请原谅。提前致谢。请帮忙。
答案 0 :(得分:2)
public static void main(String args[]) {
//with type declaration
MathOperation incrementCounter = (int a) -> a++;
//with out type declaration
MathOperation incrementCounter = a -> a++;
//with return statement along with curly braces
MathOperation incrementCounter = (int a) -> { return a++; };
//without return statement and without curly braces
MathOperation division = (int a) -> a++;
System.out.println("Increment" + tester.operate(10, incrementCounter));
interface MathOperation {
int operation(int a);
}
private int operate(int a, MathOperation mathOperation) {
return mathOperation.operation(a);
}
}
答案 1 :(得分:0)
我认为您不能仅在lambda表达式中做到这一点,但可以使用匿名类表示法:
Function<String,Integer> fct = new Function<String,Integer>() {
int counter = 0;
@Override
public Integer apply(String t) {
// ...
return ++counter;
}
};
答案 2 :(得分:0)
听起来您正在尝试使用lambda做两件事,还创建了一个增量解决方案。我建议将问题分开,并询问为什么增量解决方案需要lambda。以下是使用lambda的解决方案,但是我很难相信我会在现实世界中写过类似的东西。
interface Thing{
public int increment();
}
public class Lambda {
private static Integer counter = 0;
/**
*
*/
public static Integer testingLambda() {
Thing thing = () -> ++counter;
return thing.increment();
}
}
我可能会选择类似的东西...
public class Lambda {
private static int counter = 0;
private Lambda() {
}
public static void increment() {
counter++;
}
public static int getCounter() {
return counter;
}
答案 3 :(得分:0)
要注意的一件事是,在Stream
中使用lamda很诱人,而当我们使用Stream
时,很容易添加一个.parallel
调用来使用多线程。 这会增加一些并发问题。
一件好事是可以使用可以帮助您完成任务的类解决,AtomicInteger
提供了一种递增AtomicInteger.incAndGet
或添加AtomicInteger.addAndGet
这可用作这样的方法参考:
final int SIZE = 10_000;
AtomicInteger cnt = new AtomicInteger();
IntStream.range(0, SIZE)
.parallel().map(i -> 1)
.forEach(cnt::addAndGet);
这不是最有趣的代码,但是它将使用同步计数器递增,从而防止出现问题。我使用了一个等效的代码,该代码使用带有int
的简单计数器进行比较,并且几乎每次尝试都失败。
以下是证明该概念的快速代码。这是一个简单的循环,如果有问题,每次测试都会尝试100次,并在控制台中输出。
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class Main {
int cntInt;
AtomicInteger cntAtom;
final int SIZE = 10_000;
final int TRIES = 1_000;
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Main().testInt();
}
for (int i = 0; i < 100; i++) {
new Main().testAtomic();
}
}
public void testInt(){
int testCount = 0;
do{
cntInt = 0;
testCount++;
IntStream.range(0, SIZE)
.parallel().map(i -> 1)
.forEach(i -> cntInt += i);
}while(cntInt == SIZE && testCount < TRIES);
if(cntInt != SIZE ){
System.out.format("INTEGER Run: %d, Value: %d, Expected: %d%n", testCount, cntInt, SIZE);
}
}
public void testAtomic(){
int testCount = 0;
do{
cntAtom = new AtomicInteger();
testCount++;
IntStream.range(0, SIZE)
.parallel().map(i -> 1)
.forEach(cntAtom::addAndGet);
}while(cntAtom.get() == SIZE&& testCount < TRIES);
if(cntAtom.get() != SIZE ){
System.out.format("ATOMIC Run: %d. Value: %dm Expected: %d%n", testCount, cntAtom.get(), SIZE);
}
}
}
有时候,INTEGER可以运行很长时间,没有任何问题,但是您会注意到使用AtomicInteger
和同步方法更安全。
答案 4 :(得分:0)
这是最简单的lambda形式,可以自动增加计数器的值。计数器以0初始化。每次调用count.getAsInt()
都会返回当前计数器值,然后再递增计数器(后递增)。因此示例中的计数器返回0、1、2…。
如果使用++counter[0]
,它将是1,2,3…。
int[] counter = new int[] { 0 };
IntSupplier count = () -> counter[0]++;
count.getAsInt(); // returns 0, 1, 2…