Simeon Leyzerzon
Simeon Leyzerzon

Reputation: 19074

Convert Enumeration to a Map in Java

I'm trying in my code to use the following expression

    Map<String, String> headersMap =
             Collections.list(request.getHeaderNames())
        .stream()
        .collect(Collectors.toMap(
            name -> name,
            request::getHeader));

as shown here but Eclipse complains of type mismatch:

enter image description here

What's the correct way to accomplish this and why? Why does the one in the link not uses any casting?

UPDATES:

Considering the suggestion from @Eugene, the following monstrosity seems to make the compiler happier:

Map<String, String> headersMap = new HashMap<>();
 Collections.list(request.getHeaderNames())
 .forEach(x -> headersMap.put((String)x, (String)request.getHeader((String)x)));

Perhaps there are more succinct ways of expressing it in Java 8?

Upvotes: 2

Views: 2921

Answers (1)

Simeon Leyzerzon
Simeon Leyzerzon

Reputation: 19074

Contrary to the @Eugene's assertions, what makes the difference here is that org.eclipse.jetty.server.Request.getHeaderNames() produces an Enumeration<Object> which, consequently, being fed into Collections.list() results in an ArrayList<Object> which is the reason Java compiler doesn't accept it.

Casting the end result to (Map<String, String>), as suggested by an IDE alleviates the complaint:

Map<String, String> headersMap =
 (Map<String, String>)
 Collections.list(request.getHeaderNames())
       .stream()
       .collect(Collectors.toMap(
                name -> name,
                request::getHeader));

Apparently the pages I mentioned (here and Servlet Filter: How to get all the headers from servletRequest?) are using the original method without eventually casting it to Map<String, String> are broken to start with (as suggested by @Eugene) or work for some other obscure reason.

Perhaps someone can shed light on that mystery.

UPDATES:

Upon further investigation as prompted by @StuartMarks's comment, indeed the culprit is the version of Jetty being used. Request.getHeaderNames() is implemented differently between the two.

Version 7.6.16 (which we happened to be using) uses raw-typed Enumeration, causing the havoc:

enter image description here

whereas Jetty ver. 9.4.7 uses a typed Enumeration:

enter image description here

It explains why the article I referenced in my original question as well as the other SO mention are both correct - they simply refer to a new implementation of that method. Again, thank you to @StuartMarks for pointing it out.

Upvotes: 3

Related Questions