1

I use StringMap class as below to simplify Map declaration:

public interface StringMap extends Map<String, String> {
  interface Entry extends java.util.Map.Entry<String, String>{

  }
}
public class StringHashMap extends HashMap<String, String> implements StringMap{

}

The problem is that I can't make StringMap.Entry work the same way as StringMap. If I do this:

StringMap strings = new StringHashMap(); // this works perfectly fine
for (StringMap.Entry entry : strings.entrySet()) { // this doesn't work
}

I get this error:

Error:(402, 49) java: incompatible types: java.util.Map.Entry<java.lang.String,java.lang.String> cannot be converted to com.nicksoft.nslib.StringMap.Entry

Is there a way around it?

Edit:

I'm starting to realize this is not possible. At least it's not possible with reasonable efforts. I guess if it was I would have found someone else doing it. But if someone has some tricks that can make code more readable - let me know.

NickSoft
  • 3,215
  • 5
  • 27
  • 48
  • I believe this would categorize as [the pseudo-typedef antipattern](http://www.ibm.com/developerworks/java/library/j-jtp02216/index.html) – Jorn Vernee May 23 '16 at 11:58
  • Then I really would like to implement that antipattern. I don't care about design patterns. Thanks for stopping by and giving your opinion. – NickSoft May 23 '16 at 14:18
  • @JornVernee Well I read about it and, yes, it's bad because you can't pass the parent class when inheritor is wanted. It sucks that java does not have typedef. However I do not agree that (non-pseudo) typedef is a bad thing. I guess when you want to write in java you have to follow java's rules. Why did you write that? Now I'm not as sure I want to use it... I might still use it for internal objects that never go outside their class. – NickSoft May 23 '16 at 14:31
  • My comment wasn't all that helpful, in hindsight. But the article explains why you're getting that error. i.e. ```java.util.Map.Entry<...>``` is not a valid substitution for ```StringMap.Entry```. The solution that the article gives is not very useful though... Since we have the diamond nowadays: ```<>```. I was really just being lazy, leaving a comment instead of giving a full answer ;) But I thought it was an interesting read, so I shared. P.S. I never said ```typedef``` was bad...? – Jorn Vernee May 23 '16 at 14:42
  • From the article: "This "viral" nature is one of the factors that made reuse of C code problematic."... About the diamond - I'm (was) not a java guy. I didn't know about it. It does make it a bit nicer to read. Although you create an object once and use it many times. It doesn't help much. Anyway, since oracle got java they started extending it too fast. I try to use the minimum version I can because I'm used to enterprise linux OSs line redhad (and based) which are not updated that often. Although I think there is at least 1.7 even on CentOS 5. – NickSoft May 23 '16 at 15:02

1 Answers1

1

That is because the entrySet() method is not overloaded to return an the type com.nicksoft.nslib.StringMap.Entry.

As you cannot override the entrySet() method to force it to return your own type, then the only option you have is to rename it:

public interface StringMap extends Map<String, String> {
    interface Entry extends java.util.Map.Entry<String, String>{

    }
    Set<Entry> myEntrySet();
}
public class StringHashMap extends HashMap<String, String> implements    StringMap{
   public Set<Entry> myEntrySet() {
    //The implementation to return the set of your own entry type.
   }
}

Then your loop would look like:

for (StringMap.Entry entry : strings.myEntrySet()) { 
}
ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • It is something that would work, but I was hoping for something a bit less complex. I don't want to re-implement entrySet(). What's more important I don't want to make a copy of the entries set every time I call this method. That would not be justified by making the code more clear (by simplifying declarations). – NickSoft May 23 '16 at 14:41