我在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
一样,所以我不明白它们之间的区别。
答案 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}}方法,您的min
是Function
对象,它不是方法。您的对象有一个方法Function
,您必须使用该方法来实现您想要实现的目标,如下所示:
apply