Lambda表达式中的增量计数器

时间:2019-06-14 04:58:30

标签: java lambda

我需要编写一个Lambda函数,该函数可以自动递增计数器值。 例如-我的计数器值是0。然后,我执行lambda表达式,它将计数器值增加到1,将值1设置为counter并从lambda表达式返回此计数器值(1)。然后,下一次,当我调用lambda expression时,lambda应该将计数器值增加到2,并从lambda返回值(2)。怎么写这样的lambda。我是lambda编程的新手。如果我有一个非常简单直接的问题,请原谅。提前致谢。请帮忙。

5 个答案:

答案 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…