【问题】
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 脚本。