我强烈建议的第一件事是更新问题的标题,使其反映您的要求。您的挑战与字符串处理无关,没有什么简单的。
幸运的是,Groovy 有一些简洁的实用程序可以应对此类挑战。
节点构建器
使用 Groovy 的 NodeBuilder,您可以创建对象树。能够表示消息的树和文件夹结构。它在行动中:
import groovy.util.NodeBuilder
import groovy.util.Node
def root = new NodeBuilder().root {
message 'world'
message 'hello'
'John' {
'Work' {
message 'TPS report'
}
'Secret Stuff' {
message 'plea to mistress'
message 'rejection from ex mistress'
}
}
'Jane' {
message 'John, I know about her!'
}
}
使用此树的实例,您可以使用GPath 来执行您请求的功能:
功能一:排序
排序不是递归完成的。相反,它是按需完成的。
// Sort the messages in the root of the tree, on the fly.
assert root.message.toSorted { it.value() }.toString() == '[message[attributes={}; value=hello], message[attributes={}; value=world]]'
函数 2a:消息总数
// Count the number of messages within the 'John' folder; including 'Work' and 'Secret Stuff' folders.
assert root.John.'**'.message.size() == 3
函数 2b:平均消息长度
// Calculate the average length of the messages in the 'John' folder: 52 / 3 = 17.3333333333
assert root.John.'**'.message.sum { it.value().size() } / root.John.'**'.message.size() == 17.3333333333
奖励:访问特定消息
// Access the first message in the 'Jane' folder.
assert root.Jane.message[0].value() == 'John, I know about her!'
在所有这些情况下,我都没有使用您的 Message 类。但是通过使用 NodeBuilder 的子类来代替 Message 类很容易。
MessageTreeBuilder
可以使用自定义构建器使用消息实例填充树。但首先,让我们改进 Message 类。
@groovy.transform.Canonical
public class Message {
String text;
int size() {
return text.size()
}
}
这里是 MessageTreeBuilder
class MessageTreeBuilder extends NodeBuilder {
Object createNode(Object name, Object value) {
def payload = name == 'message' ? new Message(value) : value
[currentNode, name, payload] as Node
}
}
是的,这就是整个班级。
然后,您可以使用完全相同的树,但使用 MessageTreeBuilder 的实例而不是 NodeBuilder。
// Sort the messages in the root of the tree, on the fly.
assert root.message.toSorted { it.value() }.toString() == '[message[attributes={}; value=Message(hello)], message[attributes={}; value=Message(world)]]'
// Count the number of messages within the 'John' folder; including 'Work' and 'Secret Stuff' folders.
assert root.John.'**'.message.size() == 3
// Calculate the average length of the messages in the 'John' folder: 52 / 3 = 17.3333333333
assert root.John.'**'.message.sum { it.value().size() } / root.John.'**'.message.size() == 17.3333333333
// Access the first message in the 'Jane' folder.
assert root.Jane.message[0].value() instanceof Message
assert root.Jane.message[0].value().text == 'John, I know about her!'