我如何遍历对象的LinkedHashSet?

时间:2018-07-26 08:34:29

标签: java set

我有一个对象的LinkedHashSet(每个对象有3个实例变量),我需要对每个对象进行操作并处理字段。我如何遍历它?我的猜测是我需要使用Iterator,但是我不确定该怎么做。

3 个答案:

答案 0 :(得分:1)

当前有3种主要方法来遍历一个集合,但是该类必须实现java.lan.Iterable接口。如果是这样,我们可以执行以下操作:

常见的for-each循环:

假设一组Set<Object> set = new LinkedHashSet<>();填充有随机对象,并且我们要打印,则可以使用 for-each 循环:

for ( Object o : set )
{
  // o is the reference to the currently selected object
  System.out.println(o);
  processObject( o );
}

此循环将顺序选择集合中的每个对象,并按照主体中的定义对其进行处理。这个特定的循环将其打印到标准输出流,然后将对象传递到processObject(Object o)方法。由于这只是一个示例,因此该方法除了再次打印该值外没有其他操作。由于此循环按顺序起作用,因此在“选择”下一个对象之前,已完全处理每个对象。
for-each 循环的一个主要缺点是,我们无法在迭代过程中安全地从集合中删除任何项目。

错误的示例:

// Doing so will lead to a ConcurrentModificationException being thrown
for ( Object o : set )
{
  set.remove( o );
}

但是 for-each 循环可以用另一种方式表示。

迭代器循环:

类似于Suryakant Bhartis的答案,我们在此示例中使用java.util.Iterator

// Utilizing the iterator provided by Set#iterator()
for ( Iterator<Object> iter = set.iterator(); iter.hasNext(); /* empty*/ )
{
  // Iterator#next() returns the next object in line.
  Object o = iter.next();
  System.out.println( o );
  processObject( o );
}

直接在for循环内声明和初始化Iterator,总体上,该结构与“正常”循环(for(int i = 0; i < n;i++){})非常相似,但是在循环之后我们没有任何增量,因此第三部分保持空白。这是因为迭代器具有一个内部计数器和指向下一个对象的指针,该对象通过调用iterator#next()自动递增。但是,当多个操作需要同一个对象时,我们必须先将其存储在局部变量中,因为随后对Iterator#next()的调用将导致不同的结果,或者如果集合中没有更多元素,则返回NoSuchElementException
假设我们只是想将集合的对象传递给processObject方法,则样板代码将简化为:

for ( Iterator<Object> iter = set.iterator(); iter.hasNext(); )
{
  processObject( iter.next() );
}

迭代器的一个主要优点是,如果我们不再需要/不需要集合中的项目,则可以从集合中删除项目。如果,二手迭代器支持它,否则UnsupportedOperationException被抛出。

因此,让我们看一下删除项目。为此,我们假设我们的集合仅包含Integer值,因此Iterator返回Integer值:

for ( Iterator<Integer> iter = set.iterator(); iter.hasNext(); )
{
  // if the returned vlaue equals 3...
  if ( iter.next().intValue() == 3 )
  {
    // ... we remove it from the set 
    iter.remove();
  }
}

请注意,此操作将删除Iterator的 returned 对象,而不是下一个对象。

Java8流,Lambda和方法参考。

自Java 8(JDK 1.8或更高版本)以来,我们能够在集合API的任何类上调用流,该流可迭代整个内容并能够评估所需的内容。让我们快速看一下一些可能的操作:

// Invoke the stream and then print every object to the standard output stream
set.stream().forEach( System.out::println );
// A 'shortcut' for the above
set.forEach( Test::processObject );
// Safely removing objects from the set. (Also a 'shortcut').
set.removeIf( i -> i.intValue() == 3 );

但是,由于大多数迭代都是模糊的,所以这些稍微复杂一些。因此,建议遵循this之类的教程以完全了解上述内容。 也不建议初学者使用。

答案 1 :(得分:0)

了解该概念的简单示例解决方案。 希望对您有帮助...

rowsAffected = items.stream()                     // Stream<Model>
    .mapToInt(item -> saveItem(item, connection)) // IntStream
    .sum();                                       // int

答案 2 :(得分:0)

我将开始引用肯定的评论https://stackoverflow.com/a/51534527/4149078

但是我也建议使用 Java8流实现

    public static void main(String[] argv) {

    LinkedHashSet<String> set = new LinkedHashSet<>();

    set.add("First");
    set.add("Second");
    set.add("Third");

    set.stream().forEach(s -> {
        // Do your staff here
        System.out.println(s);
    });

    set.stream().map(s -> s.concat(" additional string")).forEach(s -> System.out.println(s));

    // Etc.
}

了解有关流点击this link

的更多信息