如何在遍历 java 列表时提前查看 'n' 元素?

how to look 'n' elements ahead while iterating through java list?

我有一个包含一些元素的链表。

 { (?i), \d+, \., \d+, (?i), \d+, \. }

现在,在迭代的时候,我需要找出三个连续的值是否为"\d+", "\.", "\d+",如果是,我需要将它们合并为一个值为"\d+\.\d+"的节点。所以,在上述操作之后,我之前的列表应该如下所示。

{(?i), \d+\.\d+, (?i), \d+, \.}

但是,由于 java 不公开链表的内部节点 class 所以我无法一次向前看一个以上的节点。我可以用下面的代码让它工作,但它看起来很难看。我想知道是否有任何干净的方法可以实现同样的目标。

LinkedList<String> l = new LinkedList<>(); //this can be ArrayList aswell. 
l.add("(?i)");
l.add("\d+");
l.add("\.");
l.add("\d+");
l.add("(?i)");
l.add("\d+");
l.add("\.");
System.out.println(l.toString());
List<Integer> indexesToBeRemoved = new ArrayList<>();
for (int i = 0; i < l.size(); i++) {
    int j = i;
    if ("\d+".equals(l.get(j))) {
        j++;
        if (j < l.size() && "\.".equals(l.get(j))) {
            j++;
            if (j < l.size() && "\d+".equals(l.get(j))) {
                l.set(i, "\d+\.\d+");
                indexesToBeRemoved.add(j);
                indexesToBeRemoved.add(--j);
            }
        }

    }
}

for (int i : indexesToBeRemoved) {
    l.remove(i);
}

System.out.println(l.toString());

O/P:
[(?i), \d+, \., \d+, (?i), \d+, \.]
[(?i), \d+\.\d+, (?i), \d+, \.]

List.subList是你的朋友,用吧。

 List<String> pattern = Arrays.asList("\d+", "\.", "\d+");
 for(int i=0; i<=l.size()-pattern.size(); i++) {
     List<String> subList = l.subList(i, i+pattern.size());
     if(subList.equals(pattern)) {
         subList.clear();
         subList.add("\d+\.\d+");
     }
 }
 System.out.println(l);

如果您习惯于使用 LinkedList,则希望使用迭代器而不是索引,因为 get(n) 是一个 O(n) 操作。既然你希望能够倒退,你必须从 listIterator() 函数中得到一个 ListIterator。

for(ListIterator<String> i = l.listIterator(); i.hasNext();){
    String element = i.next();
    if(element.equals("\d+") && i.hasNext()) {
       if(i.next().equals("\.") && i.hasNext()) {
           if(i.next().equals("\d+")) {
               i.remove();
               i.previous();
               i.remove();
               i.previous();
               i.set("\d+\.\d+");
           } else {
               i.previous();
               i.previous();
           }
        } else {
            i.previous();
        }
    }
}

这可能会被清理并变得更通用,但 ListIterator 是您在处理链表时应该使用的工具。