-1

I've created some class with custom toString() function:

public class Test {
    public String eventName;
    public Long eventTime; //timestamp
    public Integer firstEventResult;
    public Integer secondEventResult;
    // ... and dozens more variables

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder("Event(");
        stringBuilder.append("name:");
        stringBuilder.append(this.eventName);
        stringBuilder.append(", ");
        stringBuilder.append("time:");
        stringBuilder.append(this.eventTime);
        if(firstEventResult != null) {
            stringBuilder.append(", ");
            stringBuilder.append("firstEventResult:");
            stringBuilder.append(this.firstEventResult);
        }
        if(secondEventResult != null) {
            stringBuilder.append(", ");
            stringBuilder.append("secondEventResult:");
            stringBuilder.append(this.secondEventResult);
        }
        // ...
        stringBuilder.append(")");
        return stringBuilder.toString();
    }
}

and that toString() function provides me string like that:

Event(name:Test, time:123456789, firstEventResult:200)

How can I in this case convert back above string to the class again?

Pshemo
  • 122,468
  • 25
  • 185
  • 269
Iks Ski
  • 370
  • 1
  • 5
  • 19
  • 4
    try using a standard way to serialize - deserialize those objects... something like json – ΦXocę 웃 Пepeúpa ツ Sep 06 '17 at 16:38
  • Unfortunately it's important for me to use toString() method – Iks Ski Sep 06 '17 at 16:40
  • You custom-wrote a toString; you'd need to custom-write a parser. (And depending on the valid values in the event, you may need to handle the cases where the name contains a comma, etc.) – yshavit Sep 06 '17 at 16:41
  • 3
    "*it's important for me to use toString() method*" makes your question look like [X/Y problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Can you explain what are you trying to do exactly which is preventing you from using standard serialization and deserialization? – Pshemo Sep 06 '17 at 16:43
  • I'm using custom toString() because I have many classes serialized that way and I want to know if there is any solution. I don't know why people are down-voting, I need to do this that way, please be forgiving – Iks Ski Sep 06 '17 at 16:47
  • 4
    People are downvoting because you haven't shown any effort to try and solve this yourself. People are downvoting because this question has been asked many times before and finding the duplicate is as trivial as plugging your title into a search bar. People are downvoting because, as they've stated, it's not a useful problem to solve. `toString` is not meant as a reversible serialization protocol. – Sotirios Delimanolis Sep 06 '17 at 16:53
  • 1
    This has nothing to do with forgiveness. Read the help center to better understand how to use Stack Overflow (and to learn what downvotes mean). – Sotirios Delimanolis Sep 06 '17 at 16:53
  • 1
    "*because I have many classes serialized that way*" doesn't really explain much. Just because you made mistake in other places doesn't mean you need to reproduce it everywhere. Instead take your time and correct your previous mistakes. Most tasks already have proper tools to make our live easier. If you want to store objects you need serialization (standard one or if you need human readable form you can use JSON). – Pshemo Sep 06 '17 at 16:57

1 Answers1

2

If you really insist on using a custom serialization with .toString() over using a Standard serializer like GSON, then you need to write your own serializer/parser to deserialize your object, to do so you have two options here:

Option 1:

In general cases you will need to use ObjectInputStream class to get back the objects from the string using its readObject() and other relevant methods.

These are the main steps to follow:

  1. Serialize to byte array.
  2. Convert to Base64.
  3. Decode Base64 back to byte array
  4. And finally deserialize.

You can follow this OBJECT STREAMS – SERIALIZATION AND DESERIALIZATION IN JAVA EXAMPLE USING SERIALIZABLE INTERFACE article for further details.

Option 2:

Otherwise you can extract the object members using either Regex or String manipulations,for example if you know that the the format is exactly like this:

Event(name:Test, time:123456789, firstEventResult:200)
  • Starts with Event(
  • values separated with ,
  • ends with )

Then you could do the following:

  1. Convert the value pairs into a Map
  2. Create a new instance of this class and set the values from a map
public static YourClassName fromString( String str ) {
    YourClassName result = new YourClassName();

    // remove the start and ending ( not tested :P )
    String trimmed = str.substring( 6, str.length - 7 );
    String[] valuePairs = trimmed.split( ", " );
    Map<String, String> values = new HashMap<>();

    // convert value pairs into a map
    for ( String valuePair : valuePairs ) {
        String[] pair = valuePair.split( ":" );
        String key = pair[0];
        String value = pair[1];
        values.put( key, value );
    }

    // set the values one by one
    if ( values.get( "name" ) != null ) result.name = values.get( "name" );
    if ( values.get( "firstEventResult" ) != null ) result.firstEventResult = Integer.parse( values.get( "firstEventResult" ) );
    // and all others...
    return result;
}
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • 2
    You don't need to use an ObjectInputStream to parse text into an object; in fact, that's probably a misuse of that class. OIS is really meant to read objects serialized via the standard Java serialization mechanism (from the docs: "An ObjectInputStream deserializes primitive data and objects *previously written using an ObjectOutputStream*," emphasis added). If you just want to parse text and create an object, you can do that using just normal parsing. Heck, you could do it with regex in this case. Extract the snippets, and then use them to instantiate an Event. – yshavit Sep 06 '17 at 16:56