给出以下代码:
String s = "dirty";
for (Action action : actions) {
s = doAction(s, action);
}
...其中操作可以是对字符串的清理操作,例如删除非法字符或删除重复字词。
有没有办法更优雅地写这个来处理调用而不重新分配字符串?
答案 0 :(得分:0)
我不认为你可以避免重新分配字符串,因为你需要在每次迭代中获得更新的值。
至于:
有没有办法更优雅地写这个
使用流API,您可以:
String result = actions.stream() // or Arrays.stream(actions)
.reduce("dirty", (s, action ) -> doAction(s, action),
(e, a) -> {throw new RuntimeException("un-implemented");});
虽然它可以说不像你的解决方案那么可读。
答案 1 :(得分:0)
写它的递归方式是这样的:
public static void main(String[] args) {
List<Action> actions = .. //your list of Actions
String s = doActions("dirty", actions);
}
private static String doActions(String s, List<Action> actions) {
if(actions.isEmpty()) {
return s;
} else {
// apply the first Action
Action action = actions.remove(0);
String newString = doAction(s, action);
// recursively call with the new String and the remaining actions
return doActions(newString, actions);
}
}
但是正如您所看到的,您仍然可以在creation/assignement
方法中获得字符串doActions
。这是因为String
是不可变的并且无法修改。
如果您只是寻找recursive
方式来编写它,那么可以这样做。如果你真的想要摆脱新的String
创作,你需要使用StringBuilder
,正如Jacob G建议的那样。带有签名,如
void doAction(StringBuilder sb, Action action)
答案 2 :(得分:0)
您可以避免通过将其设为字段来重新分配s
public class SActions {
private String s;
SActions(String s){this.s = s;}
public void doAction(Action action){ /* apply action to s */}
public String getString() { return s; }
public static void main(String[] args) {
SActions sActions = new SActions("abc");
sActions.doAction(anAction);
System.out.println(sActions.getString());
}
}
您还可以添加一个方法来接受Actions
:
public void doAction(Collection<Action> actions) {
for (Action action : actions) {
doAction(action);
}
}
要使对象可重用,请添加一个setter:
public SActions setString(String s) {
this.s = s;
return this;//for convenience, so you can chain invocation
}
请注意,setter返回this
以便更方便地调用:
SActions sActions = new SActions(); //requiers standard constructor
sActions.setString("abc").doAction(anAction);
如果它或多或少优雅'它肯定是有争议的。