How to implement assembly (list, map?) Of complex strings in Java?

Problem. I have something like the following entries, 1000 of them:

args1=msg args2=flow args3=content args4=depth args6=within ==> args5=content args1=msg args2=flow args3=content args4=depth args6=within args7=distance ==> args5=content args1=msg args2=flow args3=content args6=within ==> args5=content args1=msg args2=flow args3=content args6=within args7=distance ==> args5=content args1=msg args2=flow args3=flow ==> args4=flowbits args1=msg args2=flow args3=flow args5=content ==> args4=flowbits args1=msg args2=flow args3=flow args6=depth ==> args4=flowbits args1=msg args2=flow args3=flow args6=depth ==> args5=content args1=msg args2=flow args4=depth ==> args3=content args1=msg args2=flow args4=depth args5=content ==> args3=content args1=msg args2=flow args4=depth args5=content args6=within ==> args3=content args1=msg args2=flow args4=depth args5=content args6=within args7=distance ==> args3=content 

I am making some kind of suggestion method. Let's say args1 = msg args2 = stream args3 = stream ==> args4 = flowbits

If the sentence contains msg, flow, and another stream, I must return the flowbits sentence.

How can i do this? I know that I have to scan (whenever a character clicks on a text area) a list or array to match and return the result, but 1000 records, how to implement it?

I am thinking of a HashMap, but can I do something like this?

<"tzd, flow, flow", "flowbits">

In addition, the arguments in the sentence may be out of order, therefore, assuming it is a stream, stream, msg, then I cannot combine anything in the HashMap, since the key is "msg, flow, flow".

What should I do in this case? Please help. Thanks a million!

+4
source share
6 answers
Key

A Map may be another Map or Set . It looks like all you need is something like Map<Set<String>, String> or maybe Map<Map<String, String>, Map.Entry<String, String>> - not sure if these "args1", "args2" matter.

+4
source

In other words, try not to execute all your logic in your parser. Separate the logic so that the parser simply detects the structure and then creates objects to help you apply the rules. The parser can easily detect arguments and use them to create a list.

If you create a class containing your arguments as follows:

 public class Arg { public int number; public String value; public Arg(int num, String val) { this.number = num; this.value = val; } @Override public String toString() { return "[Arg num=" + number + ", value=" + value + "]"; } } 

then you can put them in a simple hashtable.

 Map<Arg> argList = new HashMap<Arg>(); 

Then you can do the logic using perhaps a counter and it contains () or indexOf (), etc.

Having an Arg class makes sorting easy. If you need a list sorted by argument position, you create a Comparator for this.

 import java.util.Comparator; public class ArgNumComparator implements Comparator<Arg> { public int compare(Arg o1, Arg o2) { if (o1.number == o2.number) { return 0; } return o1.number < o2.number ? -1 : 1 ; } } 

Sorting by argument value is even easier since you can reuse compareTo () for strings.

 import java.util.Comparator; public class ArgValComparator implements Comparator<Arg> { public int compare(Arg o1, Arg o2) { return o1.value.compareTo(o2.value); } } 

Then, to sort, use Collections.sort () as follows:

 import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ArgList{ public static void main(String[] args) { //args1=msg args2=flow args3=content args4=depth args6=within ==> args5=content List<Arg> l = new ArrayList<Arg>(); // hard-coded example instead of more likely parsing l.add(new Arg(1, "msg")); l.add(new Arg(2, "flow")); l.add(new Arg(3, "content")); l.add(new Arg(4, "depth")); l.add(new Arg(5, "flow")); l.add(new Arg(6, "within")); Collections.sort(l, new ArgValComparator()); // take your pick of comparators System.out.println(l); // uses the toString() of Arg. } } 

EDIT: added the toString () method for Arg and changed the list in the example to two β€œstreams” args.

Running with the new toString code puts the following into the console:

[[Arg num = 3, value = content], [Arg num = 4, value = depth], [Arg num = 2, value = flow], [Arg num = 5, value = flow], [Arg num = 1 , value = msg], [Arg num = 6, value = within]]

As you can see, the two arguments with the value = "stream" are now next to each other. To detect a few arguments, where value = "stream" can be done this way:

 boolean flowFound = false; for (Arg arg : l){ if (arg.value.compareToIgnoreCase("flow") == 0) { if (flowFound) //already found one? { // action when second "flow" exists System.out.println("2nd flow found"); } else { flowFound = true; // found the first "flow" } } } 
+1
source

yes, you can do <"msg, flow, flow", "flowbits"> in hashmap. This is the best solution, I do not know.

0
source

At first glance, this looks good for a parser and formal grammar, not a collection. ANTLR is a popular parser generator for Java.

If the parser does not solve your problem, this is if the arguments can be displayed in any order. In this situation, I would use some Case object that combines the rules and actions and uses a simple Map<String,List<Case>> to search for instances that can be applied to the given text (you must extract individual words from the text to examine map and can combine lists returned from each probe).

I do not have time to give a complete example, but the Case object will probably look something like this:

 public interface Case { boolean evaluate(String text); String result(); } 
0
source

You can create an object and encapsulate the logic inside it for each row. If the input is exactly as described, you should be able to extract the arguments with a simple regular expression and capture group, and then call the setters for your object for each argument. Then your data structure will be just a list of these objects.

0
source

Since the order in which the lines appear is not important, you can alphabetize them when creating the key. Suppose you want to use the same sentence for msg, flow, flow and flow, msg, flow and flow, flow, msg - in alphabetical order, they are "stream, stream, msg", so you use as the key.

0
source

Source: https://habr.com/ru/post/1307782/


All Articles