2

My output is currently:

Avengers@15db9742 Avengers@6d06d69c

I need to figure out how to display the names as well, using the generic print method. I've been trying things like: GenericMethod_violette.<Avengers>print(avenger.getName()) and GenericMethod_violette.<Avengers>print(avenger.trueIdentity()) but after days on this I seem to be stuck.

My output needs to be:

Avengers@15db9742 Avengers@6d06d69c
Tony Stark, Bruce Banner

My GenericMethod_violette.java:

import java.io.ObjectInputStream.GetField;

public class GenericMethod_violette {
  public static void main(String[] args ) {
    Avengers[] avenger = { new Avengers("Tony Stark"), new Avengers("Bruce Banner")};
    
    GenericMethod_violette.<Integer>print(integers);
    GenericMethod_violette.<String>print(strings);
    GenericMethod_violette.<Avengers>print(avenger);

    
  }

  public static <E> void print(E[] list) {
    for (int i = 0; i < list.length; i++)
      System.out.print(list[i] + " ");
    System.out.println();
  }
    
}

My Avengers.java:

public class Avengers
{
   private String trueIdentity;

   public Avengers(String name)
   {
      trueIdentity = name;
    }    

   public String getName()
   {
       return trueIdentity;
   }

   public String sayTrueIdentity()
   {
       return "Hello, I'm " + trueIdentity + "!";
   }
}
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Violette
  • 21
  • 1
  • The normal way to get something to print is to add a `toString()` method. Check here: https://www.baeldung.com/java-tostring – markspace Sep 22 '20 at 03:13
  • 1
    What you want has nothing to do with Generics. You should override the `toString` in `Avengers` class and change your print statement to `list[i].toString()`. `toString` is a method of the `Object` class so you can freely call it without worrying about generic. I skipped a lot of details for brevity. I recommend you to take a look at Oracle's Java Tutorial for better understanding of concepts. – Kartik Ohri Sep 22 '20 at 03:14
  • @KartikOhri is right, each time you call `System.out.print(list[i] + " ");`, you are calling `toString` of Object which will print something like ***ClassName@hashCode***. If you want to print your own string you have to override `toString` method. – haoyu wang Sep 22 '20 at 03:19
  • If you want your desired output with the object addresses, wouldn't you just need to run a for loop again in your print statement and do `print(list[i].getName());`? You could also do `print(list[i] + " " + list[i].getName()` to get the corresponding object address, with the name that is at that object address. – DrZoo Sep 22 '20 at 03:21
  • Thank you all! I got it working with a second loop thanks to DrZoo. Everyone's answers where very helpful. Very excited to make my first post on Stackoverflow and very grateful for all the suggestions!! – Violette Sep 22 '20 at 04:42

3 Answers3

1

you can use write toString inside Avengers

      public class Avengers
        {
           private String trueIdentity;
        
           public Avengers(String name)
           {
              trueIdentity = name;
            }    
        
           public String getName()
           {
               return trueIdentity;
           }
        
           public String sayTrueIdentity()
           {
               return "Hello, I'm " + trueIdentity + "!";
           }
           // write any format you want to print
           @override
           public String toString()
           {
               return this.getName() + this.sayTrueIdentity();
           }
        }

then change your GenericMethod_violette.print method to use toString()

  public static <E> void print(E[] list) {
    for (int i = 0; i < list.length; i++)
      System.out.print(list[i] + " ");
    System.out.println();
  }

Reason for Avengers print format - Avengers@15db9742

In java all objects have a toString() method, which is invoked when you try and print the object.

    System.out.println(myObject);  // invokes myObject.toString()

This method is defined in the Object class (the superclass of all Java objects). The Object.toString() method returns a fairly ugly looking string, composed of the name of the class, an @ symbol and the hashcode of the object in hexadecimal. The code for this looks like:

    // Code of Object.toString()
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }  

So you need @overrride toString method.
Ragu
  • 373
  • 5
  • 15
0

Your print result of Avengers@15db9742 would mean that it is an object that you printed. If you want to print something meaningful, you need to override the toString() method of said object. In this case, of your Avengers object.

public String toString(){
    return trueIdentity;
}

Added notes from @markspace of java toString().

ariefbayu
  • 21,849
  • 12
  • 71
  • 92
0

The class Avengers doesn't override the Object::toString method which System.out.println implicitely uses in its implementation. I suggest you to read more at: How to override toString() properly in Java?.

However, this solution requires all the possible objects passed into the method to override such method, which you cannot guarantee. I recommend you to pass a Function<E, String> that exctracts from the generic type the field(s) as String to be printed out:

public static <E> void print(E[] array, Function<E, String> extractor) {
    for (E e: array) {
        System.out.print(extractor.apply(e) + " ");
    }
    System.out.println();
}

The usage is fairly simple (the generic type can be omitted as long as it is inferred):

// both following lines are basically identical
GenericMethod_violette.print(avenger, a -> a.getName());
GenericMethod_violette.print(avenger, Avenger::getName);
// if Avengers have more of the fields or they are to be customized, ex.:
GenericMethod_violette.print(avenger, a -> "Mr." + a.getName().toUpperCase());

Disclaimer: This solution requires Java 8. If you use Java 7 or lower, you are stick to override the Object::toString in all the expected classes:

@Override
public String toString() {
    return this.getName();
}
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183