Java 在arraylist中查找与正则表达式匹配的项

Java 在arraylist中查找与正则表达式匹配的项,java,regex,java-stream,Java,Regex,Java Stream,我正在尝试开发一个函数,该函数读取字符串的ArrayList,并且能够发现是否存在至少两个元组,它们在一组索引中具有相同的值,但在一个补充索引中不同。我使用正则表达式比较开发了此函数的一个版本,如下所示: public boolean checkMatching(){ ArrayList行=新的ArrayList(); 行。添加(“7,2,2,1,1”); 行。添加(“7,3,2,1,1”); 行。添加(“7,8,1,1,1”); 行。添加(“8,2,1,3,1”); 行。添加(“8,2,1,4

我正在尝试开发一个函数,该函数读取字符串的ArrayList,并且能够发现是否存在至少两个元组,它们在一组索引中具有相同的值,但在一个补充索引中不同。我使用正则表达式比较开发了此函数的一个版本,如下所示:

public boolean checkMatching(){
ArrayList行=新的ArrayList();
行。添加(“7,2,2,1,1”);
行。添加(“7,3,2,1,1”);
行。添加(“7,8,1,1,1”);
行。添加(“8,2,1,3,1”);
行。添加(“8,2,1,4,1”);
行。添加(“8,4,5,1,1”);
int[]索引=新的int[]{2,3};
int补充指数=1;
字符串regex=“”;
for(字符串r:行){
字符串[]rt=r.split(“,”);
regex=“[a-zA-Z0-9,-.]*[,][a-zA-Z0-9,-.]*[,][“+rt[指数[0]+]”[,][“+rt[指数[1]+]”[,][a-zA-Z0-9,-.]*”;
用于(字符串r2:行){
如果(r.equals(r2)==false){
if(Pattern.matches(正则表达式,r2)){
字符串[]rt2=r.split(“,”);
if(rt[supplementaryIndex].equals(rt2[supplementaryIndex])==false){
返回true;
}
}
}
}
}   
返回false;
}
然而,这是非常昂贵的,特别是如果有许多行。我想创建一个更复杂的正则表达式,它考虑多种选择(带有“|”条件),如下所示:

public boolean checkMatching(){
ArrayList行=新的ArrayList();
行。添加(“7,2,2,1,1”);
行。添加(“7,3,2,1,1”);
行。添加(“7,8,1,1,1”);
行。添加(“8,2,1,3,1”);
行。添加(“8,2,1,4,1”);
行。添加(“8,4,5,1,1”);
int[]索引=新的int[]{2,3};
int补充指数=1;
字符串regex=“”;
for(字符串r:行){
字符串[]rt=r.split(“,”);
正则表达式+=“[a-zA-Z0-9,-.]*[,][a-zA-Z0-9,-.]*[,][”+rt[指数[0]+“][,][”[a-zA-Z0-9,-.]*”;
正则表达式+=“|”;//或
}   
用于(字符串r2:行){
if(Pattern.matches(正则表达式,r2)){
//字符串rt2=r.split(“,”);
//if(rt[supplementaryIndex].equals(rt2[supplementaryIndex])==false){
返回true;
//}
}
}
返回false;
}

但问题是,这样我无法比较补充索引值。对于如何定义一个可以直接满足这个条件的正则表达式,您有什么建议吗?或者,有没有可能利用java streams来有效地实现这一点?

第一种方法的主要问题是,在同一个列表上有两个嵌套循环,这会使您的时间复杂度达到二次方。回想一下,这意味着对于包含100个元素的列表,内部循环的主体执行10000次,对于包含1000个元素的列表,执行1000000次,以此类推

它无助于调用内部循环主体中的
Pattern.matches(regex,r2)
。该方法的存在只是为了(作为委托目标)支持
String
操作
r2.matches(r2)
,这是一种方便的方法,可以一次性执行
Pattern.compile(regex).matcher(input).matches()
。如果必须多次应用同一个正则表达式,则应保留并重新使用
Pattern.compile(regex)
的结果

但在这里,使用正则表达式毫无意义。您已经使用
split
分解了字符串,可以通过普通数组访问每个组件。使用这个起点来编写要再次应用于字符串的正则表达式,既复杂又昂贵

只要使用类似于

//当至少一个字符串的索引值相同时,返回true
//但补充指数的值不同
Map Map=newhashmap();
for(字符串r:行){
字符串[]rt=r.split(“,”);
List key=List.of(rt[index[0]],rt[index[1]]);
字符串old=map.putIfAbsent(key,rt[supplementaryIndex]);
if(old!=null&!old.equals(rt[supplementaryIndex])返回true;
}
返回false;
这将在列表上循环一次,从数组中提取关键元素,并为
HashMap
组合一个键。有多种方法可以做到这一点。但是,虽然很容易将这些元素(如
rt[index[0]]+”、“+rt[index[1]]]
)串联起来,但使用
列表
更可取,因为它可以避免昂贵的字符串串联

代码将要检查的值放入映射中,如果以前遇到过此键,映射将返回上一个值。如果是这样,可以比较新旧值,如果不匹配,该方法可以立即返回

使用Java 8时,必须使用
Arrays.asList(rt[index[0]],rt[index[1]])
而不是
List.of(rt[index[0]],rt[index[1]])

通过更改

List key=List.of(rt[index[0]],rt[index[1]]);

List key=Arrays.stream(index.mapToObj(i->rt[i]).toList();
或者,如果您使用的Java版本早于16:

列表键
=Arrays.stream(index).mapToObj(i->rt[i]).collect(Collectors.toList());

第一种方法的主要问题是,在同一个列表上有两个嵌套循环,这使您的时间复杂度达到二次方。回想一下,这意味着对于包含100个元素的列表,内部循环的主体执行10000次,对于包含1000个元素的列表,执行1000000次,以此类推

它无助于调用内部循环主体中的
Pattern.matches(regex,r2)
。该方法仅用于支持(作为委派目标)字符串操作
r2.matches