我有一个对象的LinkedHashSet(每个对象有3个实例变量),我需要对每个对象进行操作并处理字段。我如何遍历它?我的猜测是我需要使用Iterator,但是我不确定该怎么做。
答案 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 对象,而不是下一个对象。
自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
的更多信息