Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
149 views
in Technique[技术] by (71.8m points)

Java: Why is java.util.Collections.list(Enumeration) destructive?

I had a little program that relied on getting some information from the local Network Interfaces. Then, I needed to add some functionality, which needed that information again. I didn't want to touch my tested and highly used methods. So, under the pressure of time, I decided to reuse the method, effectively translating the NetworkInterface Enumeration into an ArrayList twice (not my proudest coding moment!).

Upon testing, I noticed it doesn't really work!

Sequence of actions:

  1. I grab the NetworkInterface Enumeration from the OS once, into a class field
  2. myMethod translates the NetworkInterface Enumeration into an ArrayList, does some analysis and returns some information, to do something
  3. myMethod translates the NetworkInterface Enumeration into an ArrayList, does some analysis and returns some information, to do something else

I notice, on the second translation, the result was zero! In debug, I notice that my Enumeration has a field "i". That field: first time, it equaled 55 (the count of my IFs), second time, it equaled 0...

I provide a small piece of code that should reproduce it for your debugging pleasure (I am using Java 8):

import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;

public class CollectionsListDemo {
    public static void main(String[] args) {
        ArrayList<NetworkInterface> netFacesArList1;
        ArrayList<NetworkInterface> netFacesArList2;
        try {
            Enumeration<NetworkInterface> netFaces = NetworkInterface.getNetworkInterfaces();
            netFacesArList1 = Collections.list(netFaces);
            netFacesArList2 = Collections.list(netFaces);
        } catch (Exception e) {
            throw new RuntimeException("whatever");
        }

        System.out.println(netFacesArList1.size()); // 55, on my machine
        System.out.println(netFacesArList2.size()); // 0
    }
}

Basically, what I want to know is if there's a practical reason Collections.list() works this way... Or it's just a limitation... Or I am using wrong?

For now, I am just going to take this translation out, into a separate ArrayList, which I think I can read in different methods, without it remembering stuff from previous reads...

question from:https://stackoverflow.com/questions/65852332/java-why-is-java-util-collections-listenumeration-destructive

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's not that Collections.list(Enumeration) is "destructive". It's that Enumeration (an outdated version of Iterator) is single-use. Once you iter...enumerate through it, it returns empty and 0 elements left. The same holds true for Iterator, although a ListIterator allows you to move forwards and backwards, so it can be always "rewound" even if iterated to the end.

The reason for this becomes more obvious when you consider the supposed use case:

Enumeration<NetworkInterface> netFaces = NetworkInterface.getNetworkInterfaces();
while(netFaces.hasMoreElements()) {
    NetworkInterface iface = netFaces.nextElement();
    // do something with iface
}
// Enumeration object is now used up

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...