4

It us useful to emulate lambda in Java but currently you must implement in-place class which implement some interface...

For example a join function may get Stringator interface, so can join any List or Collection regardless of contained object:

interface Stringator<T> { String toString(T t); }

public static <T> String join(Collection<T> col, String delim, Stringator<T> s) {
    StringBuilder sb = new StringBuilder();
    Iterator<T> iter = col.iterator();
    if (iter.hasNext())
        sb.append(s.toString(iter.next()));
    while (iter.hasNext()) {
        sb.append(delim);
        sb.append(s.toString(iter.next()));
    }
    return sb.toString();
}

I don't know any standard Stringator or ToStringer interface...

This join implementation can simplify beans manipulation. For exanple to get list of books:

List<Book> books = ...;
String list =
  join(books, ", ", new Stringator<Book>{ toString(Book b) {return b.getName();} });

Note that suggestion to use standard toString violate Java convention: toString for debugging (look for JavaDoc and Java lang spec)!

UPDATE Java already have interface which work in other direction - PropertyEditor. Each it implementation can construct Object from String. I look for String from Object...

UPDATE 2. Many people think that I wrongly avoid toString. This is from Java 7 Lang Spec (section 6.1):

A method that converts its object to a particular format F should be named
toF. Examples are the method toString of class Object and the methods
toLocaleString and toGMTString of class java.util.Date.

So if I have Book objects, toString naturally must return ISBN, but that if I need to join book titles? That is why toString not so good and java.text.Format.format or other looks more natural.

gavenkoa
  • 45,285
  • 19
  • 251
  • 303
  • 1
    about this "violate Java convention" thing, do you have a link for this? because i'm not seeing it in the language spec. – Nathan Hughes Apr 05 '13 at 14:17
  • 1
    There's no concept of a standard string in the real-world is there? So I don't see how this could ever exist within Java. BigDecimal has some variations on toString(), like toEngineeringString() but there's no interface for it, I think you're just going to have to write your own! Perhaps you might standardise by using something like JSON? – Bob Flannigon Apr 05 '13 at 14:18
  • Please look to http://stackoverflow.com/questions/3615721/how-to-use-the-tostring-method-in-java – gavenkoa Apr 05 '13 at 14:22
  • Since both the eclipse and netbeans IDEs have options that automatically generate `troString()` methods for you, I am suspicious about your claim it violates java conventions. If the language creators didn't want you to override it, they would have made it final. – Colin D Apr 05 '13 at 14:23
  • @gavenkoa your link only mentions what the default `Object.toString()` does. It mentions nothing about overriding it for use in subclasses. – Colin D Apr 05 '13 at 14:25
  • Java spec say about `textual representation` which is made by analogy like this do Python by `str`/`utf` and in another object systems... Debuggers usually use `toString()` to simplify identifying object... – gavenkoa Apr 05 '13 at 14:28
  • 1
    Although there are classes that use `toString` for debugging purposes only, like `java.awt.Point` and `java.awt.Color` (see javaDocs), there are also lots of classes that use it for other reasons (like `java.util.BigInteger` or `java.util.BigDecimal`). Also, the general description here: http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#toString() doesn't even mention debugging. A textual representation can be useful for several purposes. – Lone nebula Apr 05 '13 at 14:31

4 Answers4

3

Override toString(), it does not violate any java conventions and is actually a recommended practice.

Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#toString%28%29

Colin D
  • 5,641
  • 1
  • 23
  • 35
  • Using separate interface force developers to implement method. `toString` doesn't do any such enforcement. But in any way thanks for interest to question. +1 – gavenkoa Apr 05 '13 at 14:47
1

There is no ToStringer or similar interface in std java, you can define your own, and use

String stringValue()

which is analog to intValue() longValue() etc, often used in java

AlexWien
  • 28,470
  • 6
  • 53
  • 83
1

There is java.text.Format.format but it's not very nice and is abstract class.

Java SE 8 will probably have a functor interface for transforming between two arbitrary types, one of which may be String.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
1

There's no issue with overriding toString() other than the fact that that gives you only one way of expressing your object as a string. I think ganvenkoa is suggesting something that allows you to easily express it in custom ways. Imagine if you're dealing with a Customer object whose toString() returns John Smith, but when you're joining a bunch of customers using join(...), you want the customer to be expressed as Smith, John.

One thing that I've used for that sort of thing is a utility such as com.google.common.collect.Iterables.transform(Iterable) (which in turn uses a Function) and pass the result of that to com.google.common.base.Joiner.join(Iterable). I'm hoping that will become more elegant with Java 8

Blake
  • 581
  • 4
  • 14