如何在没有先运行代码的情况下将代码传递给方法?

时间:2017-03-30 12:20:13

标签: java

请帮助我如何在java中实现以下目标。

public class TestUserFunctions {

    public static boolean equals(int val1, int val2){
        if(val1==val2){
            return true;
        } else{
            return false;
        }
    }
    public static Object iterateValue(String ittr, int iterations){
        for(int i=1; i <= iterations; i++){
            System.out.println("Printing iteration #"+i);
        }
        return ittr;
    }

    private static void ifElse(boolean condition, Object returnstr, Object elsestr){
        if(condition){
            System.out.println("TRUE");
            //Need a code here which will iterate string value only once.
        } else{
            System.out.println("FALSE");
            //Need a code here which will iterate string value thrice as specified.
        }
    }

    public static void main(String[] args){
        ifElse(equals(1, 1), iterateValue("Value", 1), iterateValue("Value", 3));
    }
}

我的上述代码在很多方面可能都有问题。我对此感到抱歉。 这里的预期输出是

TRUE
Printing iteration #1

如果ifElse(equals(1, 1), iterateValue("Value", 1), iterateValue("Value", 3));预期输出为

FALSE
Printing iteration #1
Printing iteration #2
Printing iteration #3

3 个答案:

答案 0 :(得分:2)

重点是:

ifElse(equals(1, 1), iterateValue("Value", 1), iterateValue("Value", 3));

在Java中,所有方法参数在调用发生之前都会被评估(也称为计算)。

换句话说:

  • equals(1,1)将始终为true
  • 因此总是返回第一个“值”(虽然这并不重要;因为你在两种情况下都使用相同的值)
  • 如上所述,iterateValue()的两次调用都将被执行;这意味着这个方法被调用两次,每个调用都有相应的参数。

所以,如果你只打电话给iterateValue()一次;您应将其用作参数。相反,去寻找类似的东西:

ifElse(equals(1,1), "ValueA", "ValueB"));

然后直接在第一个或第二个传入的String参数上调用iterateValue();而且只有一次。

答案 1 :(得分:1)

您需要使用Java 8 lambda表达式推迟执行if和else块以获得您想要实现的目标

import java.util.function.Supplier;

public class TestUserFunctions {

    public static Supplier<Boolean> equals(int val1, int val2){
        if(val1==val2){
            return () -> true;
        } else{
            return () -> false;
        }
    }
    public static Supplier<String> iterateValue(String ittr, int iterations){
      return () ->  {
         for(int i=1; i <= iterations; i++){
            System.out.println("Printing iteration #"+i);
         }
        return ittr;
      };
    }

    private static void ifElse(Supplier<Boolean> condition, Supplier<String> returnstr, Supplier<String> elsestr){
        if(condition.get()){
            System.out.println("TRUE");
            returnstr.get();
        } else{
            System.out.println("FALSE");
            elsestr.get();
        }
    }

    public static void main(String[] args){
        ifElse(equals(1, 1), iterateValue("Value", 1), iterateValue("Value", 3));
    }
}

使用Java&lt; 8可读性大大降低

interface Supplier<T> {
  public T get();
}

public class TestUserFunctions {

    public static Supplier<Boolean> equals(int val1, int val2){
        if(val1==val2){
          return new Supplier<Boolean>() {
            public Boolean get() { return true; }
          };
        } else{
          return new Supplier<Boolean>() {
            public Boolean get() { return false; }
          };
        }
    }
    public static Supplier<String> iterateValue(String ittr, int iterations){
      return new Supplier<String>() {
        public String get() {
          for(int i=1; i <= iterations; i++){
            System.out.println("Printing iteration #"+i);
          }
          return ittr;
        };
      };
    }

    private static void ifElse(Supplier<Boolean> condition, Supplier<String> returnstr, Supplier<String> elsestr){
        if(condition.get()){
            System.out.println("TRUE");
            returnstr.get();
        } else{
            System.out.println("FALSE");
            elsestr.get();
        }
    }

    public static void main(String[] args){
        ifElse(equals(1, 2), iterateValue("Value", 1), iterateValue("Value", 3));
    }
}

答案 2 :(得分:0)

你的问题可以更简洁地表达出来:

public class Demo() {

   static int x = 0;

   static int incrementAndReturnX() {
       x++;
       return x;
   }

   static void ifElse(boolean predicate, int t, int f) {
       if(predicate) {
          return t;
       } else {
          return f;
       }
   }

   static void main(String... args) {
       System.out.println(ifElse(false, incrementAndReturnX(), incrementAndReturnX());
   }
}

这会打印2 ..为什么会这样,我们怎么能让它返回1?

答案是Java调用方法的顺序。当它处理ifElse(true, incrementAndReturnX(), incrementAndReturnX())时,它运行作为参数传递的方法,以便获取对象或基元。 然后它会调用ifElse()

所以:

  1. Java指出true是一个原语。没事做。继续前进。
  2. Java调用incrementAndReturnX()x递增。返回1
  3. Java再次调用incrementAndReturnX()x递增。返回2
  4. Java使用它收集的值来调用ifElse(false, 1, 2)
  5. 您可以看到结果是2
  6. 我们需要的是将方法传递给ifElse()例程的一些方法,就好像它是一个对象,以便它可以选择是否运行它。在Java 7中,我们唯一能做到这一点的方法是创建包含我们方法的类,这样我们就可以传递它们。

     interface IntegerSupplier() {
          int get();
     }
    
     ...
    
     final int[] x = new int[1];
    
     IntegerSupplier incrementAndReturnX = new IntegerSupplier() {
          x[0] += 1;
          return x[0];
     }; 
    

    请注意,这是使用匿名类语法。我们在这里创建一个新类,并创建一个它的实例,而不给它起一个名字。

    我们也在数组中包装x,因为内部类只能引用final个变量,我们需要能够修改它。

     public int ifOrElse(boolean predicate, IntegerSupplier t, IntegerSupplier f) {
       if(true) {
           return t.get();
       } else {
           return f.get();
       }
     }
    

    这里的关键是增加x的代码位于if块内部之前未调用的方法中。

    从Java 8开始,我们有更简洁的方法来做同样的事情。我们可以使用所谓的 lambda 非常简洁地声明与我们的IntegerSupplier非常相似的东西:

      Supplier<Integer> incrementAndReturnX = () {
          x[0]++;
          return x;
      }
    
     public int ifOrElse(boolean predicate, Supplier<Integer> t, Supplier<Integer> f) {
       if(true) {
           return t.get();
       } else {
           return f.get();
       }
     }
    

    java.util.function.Supplier由JRE提供:我们不需要声明我们自己的)

    这种思维方式被称为函数式编程,非常强大且富有表现力。