在不做新的情况下调用函数

时间:2016-11-02 14:45:40

标签: java function static

我在Java中编写了一个sort函数和类:

public class MiscellaneousUtilities {

    /**
     * Changes a list of "First Last" to "Last, First" and "First Middle Last" to "Last, First Middle", etc.
     */
    public static Function<String, String> ToLastFirstFunction = new Function<String, String>() {
        @Override
        public String apply(String nm) {
            String[] nmarr = nm.split(" ");
            int last = nmarr.length - 1;
            String res = nmarr[last];
            if (last > 0) {
                res += ",";
            }

            for (int i = 0; i < last; i++) {
                res += " " + nmarr[i];
            }

            return res;
        };
    };
}

当我想使用它时,我不能只说MiscellaneousFunctions.ToFirstLastFunction()

我必须做一个新的MiscellaneousFunctions().ToFirstLastFunction;

我尝试在类声明前放置静态,但它只允许public,final和abstract。如果我想使用Math.min(),请查看Math类,我不必执行新的Math().min()。 Math也被定义为前面没有static的类,min()ToFirstLastFunction一样,所以我不明白它们之间的区别。

3 个答案:

答案 0 :(得分:2)

那是因为你必须用这样的apply调用该函数:

MiscellaneousFunctions.ToFirstLastFunction.apply("yourstring");

您可以添加其他static功能作为简写:

public static String toFirstLast(String str) {
    return ToLastFirstFunction.apply(str);
}

Math.min与您的解决方案之间的主要区别Math.min是一个常规static方法,而您拥有Function对象,而apply可以使用@ECHO OFF REM taken from: http://stackoverflow.com/questions/26633549/using-for-or-forfiles-batch-command-to-individually-archive-specific-files SETLOCAL SET "sourcedir=Q:\BackupMirror" FOR /f "delims=" %%a IN ( 'dir /s/b /a-d "%sourcedir%\*.*" ' ) DO ( C:\Progra~1\7-Zip\7z.exe a -t7z "%%~fa.7z" "%%~fa" -mx9 -mmt ROBOCOPY Q:\BackupMirror G:\BackupMirrorZips *.7z /e /mov ) 调用}。

答案 1 :(得分:1)

Math.min()是一个方法而不是一个函数,在Math.class中声明如下:

public int min(int a, int b) {
    ...
}

...这样的方法可以像int x = Math.min(3,2)一样直接调用。

您创建了一个名为public static的{​​{1}} 类变量 - 这不是您可以像方法一样调用的内容。但你可以使用ToLastFirstFunction界面中的方法来处理它 - 最简单的是java.util.function.Function

apply()

(我更改了标识符的大小写 - 了解Java大小写约定)

不是,你可以使用String out = MiscellaneousFunctions.toFirstLastFunction.apply("John Doe"); public static Function<...>打电话 - 我不确定为什么你认为是这样。

可以执行new MiscellaneousFunctions().toFirstLastFunction("John Doe") - 但您的编译器应警告您通过实例访问new MiscellanousFunctions().toFirstLastFunction.apply("John Doe")变量。 static是正确的方法。

因此,对您的问题的简短回答是:如果您想以这种方式调用它,请将其作为方法编写。

但如果是这样,为什么 你将操作定义为函数,而不是方法?

嗯,函数的好处是,与方法(*)不同,它们是对象 - 所以你可以传递它们,将它们放在集合中,将它们分配给变量。他们有像MiscellanousFunctions.toFirstLastFunction.apply()compose()这样的方法,它们会返回一个将此函数与另一个函数相结合的新函数。

所以你可以这样做:

andThen()

Java程序员在没有这个功能的情况下管理了几十年 - 函数在Java 8之前并不存在。但是你可以用它们做很多简洁的事情。

即便如此,这也不是将您的代码编写为绑定到静态变量的Map<String,Function<String,String> nameTranslationStrategies = new HashMap<>(); nameTranslationStrategies.put( "no change", x -> x); nameTranslationStrategies.put( "to first-last", MiscellaneousFunctions.toFirstLastFunction); nameTranslationStrategies.put( "capitalised first-last", MiscellaneousFunctions.toFirstLastFunction .andThen( s -> s.toUpperCase()); ... String nameTranslationOption = config.getProperty("nameTranslationOption"); String name = nameTranslationStrategies .get(nameTranslationOption) .apply(inputString); 的理由,因为您可以使用Function语法将普通方法作为函数进行访问:

::

另请注意,您已使用冗长的语法来定义函数:

  Function<Double,Double> logarithm = Math::log;
  double x = logarithm.apply(2.0);

...可以写成:

 public static Function<String, String> slimify = new Function<String, String>() {
    @Override
    public String apply(String s) {
         return "slim says " + s;
    }
 }

......甚至(因为这是一个单行)

public static Function<String,String> slimify = s -> {
    return "slim says " + s;
}

了解冗长的方式很有用,因为它展示了功能在幕后的运作方式。但在现实世界的代码中,较短的形式是要走的路,因为它更具表现力:代码的意图不会被杂乱隐藏。这是表达函数的一种快速简便的方法,人们经常在线使用它们而不是将它们分配给变量 - 正如我在上面的地图示例中所做的那样。

(*)我说方法不是对象。这并非严格正确 - 部分原因是您可以使用public static Function<String,String> slimify = s -> "slim says " + s; 将其作为对象获取,但也因为您可以使用Java的Reflection API将类和方法作为对象进行访问。但你不想使用反射,除非你真的知道你需要。

答案 2 :(得分:0)

Math.min()是名为public static的{​​{1}}方法,您的minFunction对象,它不是方法。您的对象有一个方法Function,您必须使用该方法来实现您想要实现的目标,如下所示:

apply