How to properly override Java toString method?

How to properly override Java toString method?

I’m struggling with my toString() method, and it’s frustrating. When I try to call toString(), it says it “can’t find Kid constructor #2, even though it’s clearly there. Here’s my code:

import java.util.*;  

class Kid {  
    String name;  
    double height;  
    GregorianCalendar bDay;  

    public Kid() {  
        this.name = "HEAD";  
        this.height = 1;  
        this.bDay = new GregorianCalendar(1111,1,1);  
    }  

    public Kid(String n, double h, String date) {  
        StringTokenizer st = new StringTokenizer(date, "/", true);  
        n = this.name;  
        h = this.height;  
    }  

    public String toString() {  
        return Kid(this.name, this.height, this.bDay); // Issue here  
    }  
}  

class Driver {  
    public static void main(String[] args) {  
        Kid kid1 = new Kid("Lexie", 2.6, "11/5/2009");  
        System.out.println(kid1.toString());  
    }  
}  

I know my toString() implementation is incorrect, especially the third parameter, but when I try to hardcode a value, it still fails. How can I fix my toString() method to properly return a string representation of my Kid object?

If you need a mutable set, wrapping Arrays.asList() with HashSet works well."

Set<String> h = new HashSet<>(Arrays.asList("a", "b", "c"));

:white_check_mark: Why This Works:

Uses Arrays.asList() to create a fixed-size list, then wraps it in a HashSet, which is mutable.

Preserves uniqueness of elements.

:x: Downside:

A bit less efficient than Set.of() since it creates an intermediate list.

Usage Example:

Set<Integer> numbers = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
numbers.add(6); // Works fine

Alright, the main issue here is that toString() is incorrectly trying to return Kid(this.name, this.height, this.bDay);, which is not valid. A straightforward fix is to properly format the string like this:

@Override
public String toString() {  
    return "Name: " + name + ", Height: " + height + ", Birthday: " + 
           bDay.get(Calendar.YEAR) + "-" + 
           (bDay.get(Calendar.MONTH) + 1) + "-" + 
           bDay.get(Calendar.DAY_OF_MONTH);
}

This is a simple and effective approach. It gets the job done without unnecessary complexity

That’s a great solution! However, I’d recommend a more structured approach using String.format()—it keeps things cleaner and easier to read, especially for formatted output.

@Override
public String toString() {  
    return String.format("Name: %s, Height: %.2f, Birthday: %04d-%02d-%02d", 
            name, height, 
            bDay.get(Calendar.YEAR), 
            bDay.get(Calendar.MONTH) + 1, 
            bDay.get(Calendar.DAY_OF_MONTH));
}

This ensures proper formatting, especially for height (%.2f for two decimal places) and date values (%04d for year, %02d for month/day). Much more readable!

If you’re dealing with a lot of Kid objects in a loop or large datasets, you might want a more efficient solution using StringBuilder. This avoids creating too many intermediate strings.

@Override
public String toString() {  
    StringBuilder sb = new StringBuilder();
    sb.append("Name: ").append(name)
      .append(", Height: ").append(height)
      .append(", Birthday: ")
      .append(bDay.get(Calendar.YEAR)).append("-")
      .append(bDay.get(Calendar.MONTH) + 1).append("-")
      .append(bDay.get(Calendar.DAY_OF_MONTH));
    return sb.toString();
}

This method reduces unnecessary string concatenations and is faster for larger objects. If performance is a concern, this is the way to go!