9
Fabian
5y

An anti-rant: I just made some code and out of nowhere it suddenly had an awesome feature that I didn't even program. No, not a euphemism for "bug", an actual feature.

Here's the story: A few months ago I made a shortcut for "System.out.println(…)" called "print(…)". Then I developed it further to also print arrays as "[1,2,3]", lists as "{1,2,3}", work with nested arrays and lists and accept multiple arguments.
Today I wanted to expand the list printing feature, which previously only worked for ArrayLists, to all types of List. That caused a few problems, but eventually I got it to work. Then I also wanted to expand it to all instances of Collection. As a first step, I replaced the two references to "List" with "Collection" and magically, no error message. So I tested it with this code:

HashMap<Integer, String> map = new HashMap<>();
map.put(1, "1");
map.put(2, "");
map.put(3, "a");
print(map);

And magic happened! The output was:

{1=1, 2=, 3=a}

That's awesome! I didn't even think yet about how I wanted to display key-value pairs, but Java already gave me the perfect solution. Now the next puzzle is where the space after the comma comes from, because I didn't program that in either.

I feel a bit like a character in "The subtle knife", who writes a barebones program to communicate with sentient elementary particles (believe me, it makes sense in context) and suddenly there's text alignment on the left and right, without that character having programmed any alignment.

Comments
  • 3
    I just found the cause… No, my code didn't recognise the HashMap as Collection at all, because a HashMap is not a Collection. Instead, it directly called "System.out.print" on the entire map, which puts it into that format. This format looks very similar to the one I use for lists, that's why I thought it was split up by my code.
  • 0
    That's not magic. If used as parameter for print/println, toString-method of an object is called and HashMap has its own implementation leading to the output you see.

    And that's true for every class in java. At the end at least Object has an implementation of toString, that's why it works with any class type, even if you don't override toString.
  • 0
    That's one of the things C# copied from Java:

    In C#, TextWriter.Write() and .WriteLine() automatically call .ToString() on any given object.
    Java does something similar to my knowledge.
  • 0
    @ddephor Sure, but Lists only give their Object ID or whatever, so I didn't expect Maps to do something else.
Add Comment