0

I have a TreeMap that contains <String, Object>. I'm looking to convert the values in the TreeMap to a List<Serializable> that contains a special value.

My Attempt

  private List<Serializable> getSecurityAttributes(
      Map<String, Object> inputTemplate, String securityAccess) {
    return inputTemplate
        .entrySet()
        .stream()
        .filter(obj -> obj.getKey().contains(securityAccess))
        .map(Map.Entry::getValue)
        .map(Serializable.class::cast)
        .collect(Collectors.toList());
  }

I'm getting a class cast exception and not quite sure why.

Specific Error:

Cannot cast org.boon.core.value.ValueList to java.io.Serializable

Leonardo Henriques
  • 784
  • 1
  • 7
  • 22
John Lippson
  • 1,269
  • 5
  • 17
  • 36
  • 1
    It's because the value is not a String. You need to cast it to Serializable if it really is one – Thiyagu Mar 28 '18 at 16:18
  • Does it need to cast to serializable? I thought since string implemented serializable I was fine. – John Lippson Mar 28 '18 at 16:20
  • You say you want a List but attempt to create a List. Maybe change the line to `.map(Serializable.class::cast)`? Hard to say without seeing actual values. – Lothar Mar 28 '18 at 16:20
  • Not all serializables are String. (example `Number`) – Thiyagu Mar 28 '18 at 16:21
  • @RyanHack `I thought since string implemented serializable I was fine`. Casting is a "do what I say" and not a "do what I mean" process. – Lothar Mar 28 '18 at 16:21
  • Your values are just `Object`s. So you need to cast or to convert to `Serializable` in some way. – lexicore Mar 28 '18 at 16:23
  • Is it possible to change the method parameter type to `Map inputTemplate`? – Bhesh Gurung Mar 28 '18 at 16:24
  • Cannot cast org.boon.core.value.ValueList to java.io.Serializable Is my error when casting each item to serializable. So I am getting a ValueList on getValue().. So I need to somehow map over the values in the valuelist? – John Lippson Mar 28 '18 at 16:25
  • @RyanHack Neither ValueList, AbstractList or List implement or extend Serializable, that's why you get the ClassCastException. So the answer to your question in this particular case is: You can't. – Lothar Mar 28 '18 at 16:29

2 Answers2

1

I casted the ValueList to a regular List and ran flatMap on it to cast each of the values.

  private List<Serializable> getSecurityAttributes(
      Map<String, Object> inputTemplate, String securityAccess) {
    return inputTemplate
        .entrySet()
        .stream()
        .filter(obj -> obj.getKey().contains(securityAccess))
        .map(Map.Entry::getValue)
        .map(List.class::cast)
        .flatMap(List::stream)
        .map(Object::toString)
        .collect(Collectors.toList());
  }
John Lippson
  • 1,269
  • 5
  • 17
  • 36
  • 1
    `.map(Map.Entry::getValue) .map(List.class::cast) .flatMap(List::stream)` can be replaced with a single `.flatMap(e -> ((List)e.getValue()).stream())`; that long chain is a typical case of overusing method references. – Holger Mar 29 '18 at 11:10
0

An Ojbect cannot necessarily be cast to a String (do not confuse calling toString() on an object, which is always possible and casting to a String which requires the object to be a subtype of String). For instance, running this: System.out.println(String.class.cast(new Object())); yields:

Exception in thread "main" java.lang.ClassCastException: Cannot cast java.lang.Object to java.lang.String
    at java.lang.Class.cast(Class.java:3369)
    at p493.Run493.main(Run493.java:42)

But System.out.println(new Object().toString()); yields java.lang.Object@2a139a55.

I do not know what you are trying to do exactly but your code would run if you replace .map(String.class::cast) by .map(Object::toString).

Oli
  • 9,766
  • 5
  • 25
  • 46
  • This is interesting. So I think this is getting closer to what I want. It's serializing the ValueList into a string, but I want to store each value in the value list as a string in this case. How can I go that extra step – John Lippson Mar 28 '18 at 16:36
  • String is final, it doesn't have subtypes – Jose Da Silva Gomes Mar 28 '18 at 19:45