如何复制Iterator对象?

时间:2017-04-20 13:52:11

标签: java arraylist

这是一个示例代码,寻找通用解决方案。

   List<String> names = new ArrayList<String>();
    for(int i=0; i<names.size()-1; i++){
        for(int j=i+1; j<names.size(); j++){
            if(names.get(i) == names.get(j)) {
                //return true;
            }
        }
    }

我希望通过增强的for循环替换上面的for循环。 所以试过这样试过。 通过迭代器替换上面的for循环:

    String name;
    Iterator<String> itr2;
    Iterator<String> itr1 = names.iterator();
    while(itr1.hasNext()) {
    // for(name=itr1.next(); itr1.hasNext(); ) {
        name = itr1.next();  // iterating itr1
        itr2 = itr1;
        while(itr2.hasNext()){
            if(name.equalsIgnoreCase(itr2.next())) {  // iterating itr2
                return true;
            }
        }
    }

我们正在迭代itr2,但itr1也在改变。这是因为它确定了itr1 = itr2。是否可以复制迭代器对象而不是分配? 相反,迭代器或任何其他逻辑也欢迎。

感谢。

4 个答案:

答案 0 :(得分:1)

如果您想使用增强版,则无法直接访问迭代器,无论如何都不能重新分配迭代器。

相反,请尝试使用子列表和其他索引计数器:

List<String> names = Arrays.asList( "a", "b", "a", "b", "c" );

int i = 0;
for( String n : names.subList( 0, names.size() - 1) ) {
  for( String s : names.subList( i + 1, names.size() ) ) {
    if( n.equals( s )) {
      return true;
    }
  }

  i++;
}

这并不比原始版本好,仅用于教育目的。可能有更好的方法来实现您的实际目标。

或者,使用Java 8可以使用流:

boolean hasDuplicates = IntStream.range( 0, names.size() - 1 )
  .filter( i -> names.subList( i + 1, names.size() ).contains( names.get( i ) ) )
  .findAny()
  .isPresent();

答案 1 :(得分:0)

在某种程度上,要复制迭代器,您需要创建一个新的迭代。所以最简单的事情就是

[{"model":"MAF","paramname":"CascDefaultSpreadOverride","minvalue":"0","maxvalue":"100","description":"The defaault repo spread override to use for CASC positions.","defaultvalue":1.0,"value":1.0,"datatype":"FLOAT"},{"model":"MAF","paramname":"DefaultLotSize","minvalue":"1","maxvalue":"1000","description":"The minimum lot size that must be met for a collateral allocation.","defaultvalue":1.0,"value":1.0,"datatype":"INTEGER"},{"model":"MAF","paramname":"HtbColdHaircut","minvalue":"0","maxvalue":"100","description":"The haircut to apply to positions with a Cold HTB category.","defaultvalue":0.1,"value":0.1,"datatype":"FLOAT"},{"model":"MAF","paramname":"HtbExtraHotHaircut","minvalue":"0","maxvalue":"100","description":"The haircut to apply to positions with a Extra-Hot HTB category.","defaultvalue":0.9,"value":0.9,"datatype":"FLOAT"},]

当然,如果你不得不制作一个新的对象,并且只是检查重复项,我只需迭代一次列表,如果我还没有看到这个值,就加入像HashMap这样的字典。 / p>

答案 2 :(得分:0)

好像你试图找出列表中是否有重复项(忽略大小写)。您不一定要使用for循环。如果您要查找简单的truefalse值。你可以:

public boolean hasDuplicatesIgnoreCase(List<String> names)
{
    return names.stream()
            .map(String::toLowerCase)
            .distinct()
            .collect(Collectors.toList())
            .size() != names.size();
}

这不是您提出的问题的答案,但可能是您问题的解决方案。否则@Thomas会使用子列表获得最佳答案。

答案 3 :(得分:0)

好像你想检查一个列表是否已经有一个名字,如果存在则返回true?我不确定它是否正确使用,但我设法以这种方式实现,以达到您要求的效果。

    List<String> names = Arrays.asList( "a", "b", "c", "d", "a" );
    final Set<String> set = new HashSet<>();

    for (String name: names) {
        if (!set.add(name)) return true;
    }

    return false;

当已添加元素时,set.add返回false,因此尝试这样做会告诉我们该名称是否已存在。