java - ArrayList 中字符串的唯一实例

标签 java arraylist groovy

我对 Java 很陌生。我正在构建一个数组列表来保存 Git 提交中的部分文本。我在 Jenkins 内的 Groovy 脚本中运行它。

 def commits = sh script: """ git log ${previous_tag}..HEAD --oneline --decorate""", returnStdout: true
 def array = commits.split("\\n");

ArrayList<String> mystats = new ArrayList<>(array.length);
 for(int i =0; i < array.length; i++) {
    Pattern pattern = Pattern.compile("^\\w{7}\\s(MYSTATS-|mystats-)");
    Matcher matcher = pattern.matcher(array[i]);
  if(matcher.find()) {
     mystats.add(array[i]) 
  }
 }

然后我想做的是创建另一个数组来保存唯一值(因此不要重复任何内容),并且被告知 HashSet 是最好的方法,因为它会拒绝重复的值

// Put all unique mystats matches into a set
 Set<String> mystats_set = new HashSet<String>(mystats.size());
 for(int i =0; i < mystats.size(); i++) {
    Pattern pattern = Pattern.compile("(MYSTATS-|mystats-)\\w+");
    Matcher matcher = pattern.matcher(mystats[i]);
  if(matcher.find()) {
     String id = matcher.group().toUpperCase().toString();
    def jira_json = sh script: '''curl --cert ../certs/dev_cert.p12:password https://jira.dev.organisation.co.uk:port_number/rest/api/2/issue/${id}''', returnStdout: true
     mystats_set.add("[" + id + "](https://jira.dev.organisation.co.uk/browse/" + id + ")");
  }
 } 

当它运行时,我得到

java.io.NotSerializableException: java.util.regex.Matcher
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.HashMap.internalWriteEntries(HashMap.java:1785)
at java.util.HashMap.writeObject(HashMap.java:1362)
at sun.reflect.GeneratedMethodAccessor202.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.TreeMap.writeObject(TreeMap.java:2438)
at sun.reflect.GeneratedMethodAccessor204.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:132)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:429)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:408)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:356)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:78)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:236)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:224)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

原因:发生的异常: 在现场本地人 在字段父级中 在现场调用者中 在字段 e 实地计划 在现场线程中 在对象 org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@4f76de19

经过一番阅读后,似乎 Set 不可序列化?如果是这种情况,我怎样才能拥有一个仅保存唯一值并拒绝重复条目的 ArrayList?

最佳答案

好吧,添加完整的堆栈跟踪后,现在看来 Matcher 是问题所在,因为它不可序列化

你检查过吗this

我引用:

you would have noticed a problem:

java.io.NotSerializableException: java.util.regex.Matcher This occurs because the matcher local variable is of a type (Matcher) not considered serializable by Java. Since pipelines must survive Jenkins restarts, the state of the running program is periodically saved to disk so it can be resumed later (saves occur after every step or in the middle of steps such as sh). ...

查看链接以获取更多信息 这篇文章建议对声明 Matcher 的方法使用注释 @NonCPS 。因为我再次引用:

Such a method will be treated as “native” by the Pipeline engine, and its local variables never saved

例如,

@NonCPS
public void doSomeWork(){
    ArrayList<String> mystats = new ArrayList<>(array.length);
    for(int i =0; i < array.length; i++) {
        Pattern pattern = Pattern.compile("^\\w{7}\\s(MYSTATS-|mystats-)");
        Matcher matcher = pattern.matcher(array[i]);
        if(matcher.find()) {
            mystats.add(array[i]) 
        }
    }
}

对于使用 Matcher 的代码的第二部分也是如此

基于您发布的答案的另一个解决方案,使用 transient 您必须在方法之外声明 Matcher 才能使用 transient 我不确定您的代码的上下文,或者您是否可以声明 Matcher 并在稍后使用它,例如:

transient Matcher matcher = null;

def commits = sh script: """ git log ${previous_tag}..HEAD --oneline --decorate""", returnStdout: true
def array = commits.split("\\n");

ArrayList<String> mystats = new ArrayList<>(array.length);
for(int i =0; i < array.length; i++) {
    Pattern pattern = Pattern.compile("^\\w{7}\\s(MYSTATS-|mystats-)");
    matcher = pattern.matcher(array[i]);
    if(matcher.find()) {
        mystats.add(array[i]) 
    }
}

代码的第二部分也是如此,除非它们位于同一类(范围)中,否则无需重新声明 Matcher

关于java - ArrayList 中字符串的唯一实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41124238/

相关文章:

java - 同时进行字符串和数字解析的语义谓词

Java Http(s)URLConnection java.io.IOException : Server returned HTTP response code: 403

grails - 不使用 Controller 逻辑的Grails urlMappings操作和 Controller 行为

java - 阻止 schemagen 将父类(super class)添加到模式中?

Android ArrayList 迭代器返回 null

java - 从 arraylist<Object> 中删除重复的字符串

java - 如何按第二个词对列表进行排序?

groovy - 在 Sublime Text 3 中运行 Groovy

grails - Grails Mail 1.0插件上的问题

java - 无法创建 bean 抛出异常 Autowiring 依赖项注入(inject)失败,无法 Autowiring 字段