【发布时间】:2020-04-22 15:18:51
【问题描述】:
我正在做以下编程练习:Moves in squared strings (I)。声明是:
给定一个 n 行字符串,每个子字符串为 n 个字符 长:例如:
s = "abcd\nefgh\nijkl\nmnop"
我们将研究这个正方形字符串的一些变换。
Vertical mirror: vert_mirror (or vertMirror or vert-mirror) vert_mirror(s) => "dcba\nhgfe\nlkji\nponm" Horizontal mirror: hor_mirror (or horMirror or hor-mirror) hor_mirror(s) => "mnop\nijkl\nefgh\nabcd"或打印:
垂直镜像|水平镜像abcd --> dcba |abcd --> mnop efgh hgfe |efgh ijkl ijkl lkji |ijkl
efgh mnop ponm |mnop abcd任务:
Write these two functions和
high-order function oper(fct, s) where fct is the function of one variable f to apply to the string s (fct will be one of vertMirror, horMirror)示例:
s = "abcd\nefgh\nijkl\nmnop" 操作(vert_mirror, s) => “dcba\nhgfe\nlkji\nponm”操作(hor_mirror,s)=> "mnop\nijkl\nefgh\nabcd"
我需要一些帮助,因为这是我第一次需要将函数作为方法的参数传递。最初的测试用例是(取自练习):
import static org.junit.Assert.*;
import org.junit.Test;
public class OpstringsTest {
private static void testing(String actual, String expected) {
assertEquals(expected, actual);
}
@Test
public void test() {
System.out.println("Fixed Tests vertMirror");
String s = "hSgdHQ\nHnDMao\nClNNxX\niRvxxH\nbqTVvA\nwvSyRu";
String r = "QHdgSh\noaMDnH\nXxNNlC\nHxxvRi\nAvVTqb\nuRySvw";
testing(Opstrings.oper(Opstrings::vertMirror, s), r);
s = "IzOTWE\nkkbeCM\nWuzZxM\nvDddJw\njiJyHF\nPVHfSx";
r = "EWTOzI\nMCebkk\nMxZzuW\nwJddDv\nFHyJij\nxSfHVP";
testing(Opstrings.oper(Opstrings::vertMirror, s), r);
System.out.println("Fixed Tests horMirror");
s = "lVHt\nJVhv\nCSbg\nyeCt";
r = "yeCt\nCSbg\nJVhv\nlVHt";
testing(Opstrings.oper(Opstrings::horMirror, s), r);
s = "njMK\ndbrZ\nLPKo\ncEYz";
r = "cEYz\nLPKo\ndbrZ\nnjMK";
testing(Opstrings.oper(Opstrings::horMirror, s), r);
}
}
我尝试了以下实现:
import java.util.function.*;
class Opstrings {
public static String vertMirror (String string) {
String[] words = string.split("\\s+");
StringBuilder sb = new StringBuilder();
for(String word : words){
sb.append(new StringBuilder(word).reverse()+"\n");
}
return string.strip().toString();
}
public static String horMirror (String string) {
return new StringBuilder(string).reverse().toString();
}
public static String oper/*????️*/(Consumer<String> operator, String s) {
return operator.accept(s);
}
}
而当我们执行前面的代码时,编译器会输出:
./src/main/java/Opstrings.java:15:错误:不兼容的类型:void 无法转换为字符串 返回 operator.accept(s); ^ 1 个错误
我了解 Consumer 被定义为返回 void。所以然后我决定进行调查,我读到 Callable 能够返回结果。于是我尝试了:
import java.util.concurrent.Callable;
class Opstrings {
public static String vertMirror (String string) {
String[] words = string.split("\\s+");
StringBuilder sb = new StringBuilder();
for(String word : words){
sb.append(new StringBuilder(word).reverse()+"\n");
}
return string.strip().toString();
}
public static String horMirror (String string) {
return new StringBuilder(string).reverse().toString();
}
public static String oper/*????️*/(Callable operator, String s) {
return operator.accept(s);
}
}
但是这次我们的编译器说我们不能在需要 String 时调用没有参数的函数(来自测试用例):
./src/test/java/OpstringsTest.java:14:错误:不兼容的类型: 无效的方法引用 测试(Opstrings.oper(Opstrings::vertMirror, s), r); ^ 类 Opstrings 中的方法 vertMirror 不能应用于给定类型 必需:字符串 发现:没有参数 原因:实际参数列表和形式参数列表的长度不同。/src/test/java/OpstringsTest.java:17:错误:不兼容的类型: 无效的方法引用
另外,我也看过:
- How to pass a function as a parameter in Java?
- https://www.geeksforgeeks.org/java-8-consumer-interface-in-java-with-examples/
- Returning Method value inside a Consumer expression
- Java 8 lambda Void argument
- https://www.baeldung.com/java-runnable-callable
- https://www.arquitecturajava.com/java-callable-interface-y-su-uso/
您能帮我弄清楚我们如何将函数式接口作为方法的参数传递并返回其结果吗?
编辑:正如@JB Nizet 所说,它可以使用 UnaryOperator 来完成:
import java.util.function.*;
class Opstrings {
public static String vertMirror (String string) {
String[] words = string.split("\\s+");
for(int i = 0; i < words.length; i++){
words[i] = new StringBuilder(words[i]).reverse().toString();
}
return String.join("\n",words);
}
public static String horMirror (String string) {
String[] words = string.split("\\s+");
StringBuilder sb = new StringBuilder();
for(int i = words.length-1; i >= 0; i--){
sb.append(words[i]+"\n");
}
return sb.toString().strip();
}
public static String oper/*????️*/(UnaryOperator<String> operator, String s) {
return operator.apply(s);
}
}
【问题讨论】:
标签: java function methods lambda java-8