I'm developing a program that needs to read data in from text files and store them in a hierarchical data structure. Here is example input and the data structure in the way Perl would parse it:
(this is for chatting robots. + is what the human says, - is how the bot replies (can have more than one - for random responses), and * are conditionals)
In Perl, building this data structure is easy, as is getting data back from it. For instance
So when porting this to Java, I decided to use HashMaps that would contain more HashMaps. Here's parts of my Java code:
Is there a more efficient way of handling the data structure than what I'm doing here?
Cuvou.com | My personal homepage
(this is for chatting robots. + is what the human says, - is how the bot replies (can have more than one - for random responses), and * are conditionals)
Code:
> topic testing
+ hello bot
- Hello human.
- Hi.
+ my name is *
* <get name> == <star> => I know, you've told me before.
- <set name=<star>>Nice to meet you!
- <set name=<star>>I'll remember your name.
< topic
$VAR1 = {
topics => {
testing => {
"hello bot" => {
reply => {
0 => "Hello human.",
1 => "Hi.",
}
},
"my name is *" => {
reply => {
0 => "<set name=<star>>Nice to meet you.",
1 => "<set name=<star>>I'll remember your name.",
},
condition => {
0 => "<get name> == <star> => I know, you've told me your name already.",
},
},
},
},
};
In Perl, building this data structure is easy, as is getting data back from it. For instance
Code:
$data->{topics}->{testing}->{'hello bot'}->{reply}->{1} = "Hi.";
So when porting this to Java, I decided to use HashMaps that would contain more HashMaps. Here's parts of my Java code:
Code:
private HashMap topics = new HashMap(); // Main reply structure
...
private boolean parse(String[] code) {
// Track some temporary variables.
String topic = "random"; // Default topic=random
int lineno = 0; // Track line numbers
boolean comment = false; // In a multi-line comment
boolean inobj = false; // Trying to parse an object
String objname = ""; // Name of the current object
Vector objbuf = null; // Object code buffer
String ontrig = ""; // Current trigger we're parsing
int repcnt = 0; // Reply counter
int concnt = 0; // Condition counter
String lastcmd = ""; // Last command code
String isThat = ""; // Is a %Previous trigger.
...
else if (cmd.equals("+")) {
// + TRIGGER
say("\tTrigger pattern: " + line);
if (isThat.length() > 0) {
// TODO
}
else {
// Initialize the sub-hashmaps.
[COLOR=red]HashMap trigspace = new HashMap();
HashMap replyspace = new HashMap();
HashMap condspace = new HashMap();
trigspace.put("reply",replyspace);
trigspace.put("condition",condspace);[/color]
// Do any triggers exist for this topic yet?
if (topics.containsKey(topic) == false) {
say("\tInitializing topic space for topic: " + topic);
HashMap topicspace = new HashMap();
topics.put(topic, topicspace);
}
// Add the (empty) trigger space to it.
say("\tInitializing trigger space for pattern: " + line);
[COLOR=red]HashMap topicspace = (HashMap) topics.get(topic);
topicspace.put(line, trigspace);
topics.put(topic, topicspace);[/color]
}
// Init some temp vars for the following commands.
ontrig = line;
repcnt = 0;
concnt = 0;
}
...
else if (cmd.equals("-")) {
// - REPLY
if (ontrig.equals("")) {
cry("Response found before trigger!");
continue;
}
say("\tResponse: " + line);
if (isThat.length() > 0) {
// TODO
}
else {
[COLOR=red]// Fetch the trigger space.
HashMap topicspace = (HashMap) topics.get(topic);
HashMap trigspace = (HashMap) topicspace.get(ontrig);
HashMap replyspace = (HashMap) trigspace.get("reply");
// Add this reply.
replyspace.put(repcnt, line);
// Rebuild the hashmaps.
trigspace.put("reply", replyspace);
topicspace.put(ontrig, trigspace);
topics.put(topic, topicspace);[/color]
}
repcnt++;
}
Is there a more efficient way of handling the data structure than what I'm doing here?
Cuvou.com | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'