结构化涉及串拆分
【问题】
for all the subclasses thats stats with ~ I want to separate into 2 values and then join it to tail of an Array variable called "attributes"example
~ public void visitMethod(org.apache.bcel.classfile.Method arg0): 4
SUB_NAME =public void visitMethod(org.apache.bcel.classfile.Method arg0)
CC=4
which I want and join it to tail of an Array variable called "attributes"
String SUB_NAME = metadata[20];
int CC =Integer.parseInt(metadata[19]);
this is the text file i am parsing
gr.spinellis.ckjm.ClassVisitor 13 2 0 14 74 34 2 14 9 0.6042 431 0.8750 1 0.7273 0.2404 0 0 31.5385
~ public void visitMethod(org.apache.bcel.classfile.Method arg0): 4
~ public void registerCoupling(String arg0): 4
~ public void end(): 5
~ public void <init>(org.apache.bcel.classfile.JavaClass arg0, gr.spinellis.ckjm.ClassMetricsContainer arg1): 1
~ public gr.spinellis.ckjm.ClassMetrics getMetrics(): 1
~ private void incRFC(String arg0, String arg1, org.apache.bcel.generic.Type[] arg2): 1
~ public void start(): 1
~ void registerMethodInvocation(String arg0, String arg1, org.apache.bcel.generic.Type[] arg2): 1
~ public void visitField(org.apache.bcel.classfile.Field arg0): 1
~ public void visitJavaClass(org.apache.bcel.classfile.JavaClass arg0): 5
~ void registerFieldAccess(String arg0, String arg1): 2
~ static String className(org.apache.bcel.generic.Type arg0): 3
~ public void registerCoupling(org.apache.bcel.generic.Type arg0): 1
gr.spinellis.ckjm.ClassMetricsContainer 3 1 0 4 18 0 2 3 2 0.0000 66 1.0000 0 0.0000 0.5556 0 0 20.6667
~ void <init>(): 1
~ public gr.spinellis.ckjm.ClassMetrics getMetrics(String arg0): 2
~ public void printMetrics(gr.spinellis.ckjm.CkjmOutputHandler arg0): 3
gr.spinellis.ckjm.MetricsFilter 7 1 0 6 30 11 2 6 5 0.6667 218 1.0000 0 0.0000 0.2000 0 0 29.8571
~ public static boolean isJdkIncluded(): 1
~ static void processClass(gr.spinellis.ckjm.ClassMetricsContainer arg0, String arg1): 3
~ public static void runMetrics(String[] arg0, gr.spinellis.ckjm.CkjmOutputHandler arg1): 2
~ public static boolean includeAll(): 2
~ static void <clinit>(): 1
~ public static void main(String[] arg0): 7
~ public void <init>(): 1
gr.spinellis.ckjm.PrintPlainResults 2 1 0 3 8 0 1 2 2 0.0000 24 1.0000 0 0.0000 0.6250 0 0 10.5000
~ public void handleClass(String arg0, gr.spinellis.ckjm.ClassMetrics arg1): 1
~ public void <init>(java.io.PrintStream arg0): 1
gr.spinellis.ckjm.MethodVisitor 11 2 0 21 40 0 1 21 8 0.5500 209 1.0000 1 0.9474 0.1736 0 0 17.6364
~ public void visitINSTANCEOF(org.apache.bcel.generic.INSTANCEOF arg0): 1
~ public void visitLocalVariableInstruction(org.apache.bcel.generic.LocalVariableInstruction arg0): 2
~ public void visitCHECKCAST(org.apache.bcel.generic.CHECKCAST arg0): 1
~ private boolean visitInstruction(org.apache.bcel.generic.Instruction arg0): 4
~ public void visitInvokeInstruction(org.apache.bcel.generic.InvokeInstruction arg0): 2
~ public void visitReturnInstruction(org.apache.bcel.generic.ReturnInstruction arg0): 1
~ public void visitArrayInstruction(org.apache.bcel.generic.ArrayInstruction arg0): 1
~ public void visitFieldInstruction(org.apache.bcel.generic.FieldInstruction arg0): 1
~ void <init>(org.apache.bcel.generic.MethodGen arg0, gr.spinellis.ckjm.ClassVisitor arg1): 1
~ public void start(): 5
~ private void updateExceptionHandlers(): 3
gr.spinellis.ckjm.CkjmOutputHandler 1 1 0 4 1 0 3 1 1 2.0000 1 0.0000 0 0.0000 1.0000 0 0 0.0000
this is my passing logic of code
public List<Metrics> readMetricFromCSV(String fileName) {
List<Metrics> metricsss = new ArrayList<>();
Path pathToFile = Paths.get(fileName);
// create an instance of BufferedReader
// using try with resource, Java 7 feature to close resources
try (BufferedReader br = Files.newBufferedReader(pathToFile,
StandardCharsets.US_ASCII)) {
// read the first line from the text file
String line = br.readLine();
while (line != null && !line.isEmpty()) { // loop until all lines
// are read
String[] attributes = line.split(" "); // the file, using a comma as the delimiter first 18 values
String str = line;
String[] arr1 = str.split("~ ");// the file, using a comma as the delimiter next 2 values
String[] arr2 = arr1[1].split(": ");
String SUB_NAME = arr2[0], CC = arr2[1];
// System.out.println("SUB_NAME " + SUB_NAME + ", CC Value: " + CC);
Metrics valueOfMetric = createMetric(attributes+SUB_NAME+CC);
metricsss.add(valueOfMetric); // adding metric into ArrayList
br.readLine();
line = br.readLine();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
【回答】
复述一下过程:过滤出含“~”的行,按“:”分成两部分,第1部分去掉“~”,命名为SUB_NAME,第2部分命名为CC。用Java硬编写太麻烦,可以用SPL实现,很简单:
A |
|
1 |
=file("d:\\source.txt").import@si() |
2 |
=A1.select(left(~,2)=="~") |
3 |
=A2.(~.split@t(":")) |
4 |
=A3.new(mid(~(1),3):SUB_NAME,~(2):CC) |
A1:读取source.txt文件内容,读成单字段串构成的序列。
A2:选出含“~”的数据。
A3:将A2序列中的字符串成员按照分隔符“:”拆成成员个数为2的序列。
A4:由A3生成一个字段为SUB_NAME和CC的二维表,SUB_NAME列的数据来自A3每个序列成员的第一个成员并去掉“~”,CC列的数据来自A3每个序列成员的第二个成员。
这段代码可以方便地集成进Java,参考Java 如何调用 SPL 脚本。