使用Enumeration <e>的hasMoreElements()和nextElement()方法打印列表,第1次成功,第2次添加失败后添加了一些元素

时间:2016-02-25 05:17:52

标签: java enumeration

我是Java的新手,正在尝试学习Enumeration的hasMoreElements()和nextElement()方法。我将一些元素添加到p1列表中,同时从p1列表中删除了其他元素后,我尝试打印所有内容,但是,它没有这样做?为什么会这样?

Properties p1 = new Properties();

try (OutputStream os1  = new FileOutputStream("xanadu123.properties")) {

    //set the properties value
    p1.setProperty("database", "localhost");
    p1.setProperty("1", "one");
    p1.setProperty("2", "two");

} catch (IOException e) {
    e.printStackTrace();
}

Enumeration<Object> eString1 = p1.elements();
while (eString1.hasMoreElements()) {
    System.out.println(eString1.nextElement());
}

System.out.println("after printing eString1");

p1.setProperty("3", "three");
p1.remove("2");

System.out.println("before printing eString1 again");

while (eString1.hasMoreElements()) {
    System.out.println(eString1.nextElement());
}

输出:

two
one
localhost
after printing eString1
before printing eString1 again

3 个答案:

答案 0 :(得分:2)

这里有两件事要注意:

  1. elements()从属性创建枚举。一旦它被创建,它就与属性本身断开连接。这意味着之后再添加一个属性将不会添加到枚举
  2. 枚举是'一次'对象,类似于迭代器。这意味着您可以循环遍历元素一次,之后,hasMoreElements每次调用时都会返回false。
  3. 鉴于这两个事实,第二次印刷什么都不打印是完全合理的

答案 1 :(得分:2)

在再次使用之前不要忘记重置枚举。

eString1 = p1.elements();

while (eString1.hasMoreElements()) {
    System.out.println(eString1.nextElement());
}

答案 2 :(得分:2)

基本答案是,如果您修改了您要枚举的内容(在本例中为Enumeration),则无法依赖Properties工作。完成后,您构建的Enumeration可能不再有效。

较新版本的EnumerationIterator,方式相同,但某些 Iterator提供remove方法除外这允许你删除&#34;当前元素&#34;从一个集合而不破坏迭代器。 (但是你必须使用remove的{​​{1}}方法;你不能使用任何其他机制来删除元素,否则你可能会破坏迭代器。)

基本原因是IteratorEnumeration包含有关您要枚举的实体的状态信息。如果您修改该实体,则状态信息可能不再有效。例如,假设您正在迭代Iterator。最有可能的是,迭代器将包含一个“&#34; current&#34;数组的索引。如果你然后在ArrayList的前面插入一些东西,那个索引所指向的元素将成为一个不同的元素,下次你在迭代器上调用ArrayList时,它会看到该索引处的元素并返回上次返回的相同元素。在您的情况下,我猜测next中保存的一条状态信息是一个Enumeration实例变量,上面写着&#34;我已经到达终点了吗?&#34 ;到达boolean的末尾后,该变量将变为Properties。如果您随后添加了更多属性,那么&#34;枚举结束&#34;变量仍然是真的,即使它在这一点上实际上是错误的。

尝试设置trueEnumerators以便他们在底层实体发生变化时自行调整是不切实际的。 Iterators对象(或Properties或其他对象)需要跟踪从中创建的每个ArrayListEnumerator,然后查找所有这些对象并进行调整无论什么时候完成,都会改变Iterator;或者每个PropertiesEnumerator都需要一种方法来查询Iterator询问它,自上次检查以来发生了哪些变化?其中任何一个都会非常复杂。还要考虑Properties是一个哈希表,因此当您添加新元素时,可以将其添加到哈希表中的任何存储桶中。如果Properties已经扫描过该存储桶,那么在您添加新元素后,如何知道再返回并再次扫描?我相信Enumerator以这种方式工作可能,但它会非常低效,混乱和复杂。