Need assistance with question on java generics [duplicate] - java

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 2 years ago.
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 + "!";
}
}

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.

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().

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();
}

Related

Why does System.out.println applied to this object print this phrase? [duplicate]

This question already has answers here:
How to use the toString method in Java?
(13 answers)
Closed 3 years ago.
I've got two classes, below. When I run the class TestSimple, it prints out "blueblueblue is blue repeated". That print statement is executed as System.out.println(item) which is an instance of the Simple() class. I've never seen an object print out as a phrase before, and I'm having a hard time pinning down why this is happening.
I see that there is a method in the Simple class called toString which should print this out when it is called, but I don't see that method called anywhere. What's going on here?
public class Simple {
private String word;
private String phrase;
public Simple(int number, String w) {
word = w;
phrase = mystery(number, w);
}
private String mystery(int num, String s) {
String answer = "";
for (int k=0; k<num; k++) {
answer = answer + s;
}
return answer;
}
public String toString() {
return phrase + " is " + word + " repeated";
}
}
And
public class TestSimple{
public void print() {
Simple item = new Simple(3, "blue");
System.out.println(item);
}
public static void main(String[] args) {
new TestSimple().print();
}
}
System.out is a PrintStream, PrintStream.println(Object) (from the linked Javadoc) calls at first String.valueOf(x) to get the printed object's string value and String.valueOf(Object) returns the value of obj.toString()

Trying to loop through an array within an array

I am trying to print each part of my noteArray (eg: 19, and then "D" as separate parts) But by using a For loop I get an a mumble up print message for each line. The "processNotes(noteArray)" method is how I want my output to look.
Any help would be much appreciated!
public class question2 {
public static void main(String[] args) {
Note[] noteArray = new Note[5];
noteArray[0] = new Note(19, "D");
noteArray[1] = new Note(10, "C");
noteArray[2] = new Note(23, "F");
noteArray[3] = new Note(20, "B");
noteArray[4] = new Note(32, "C");
processNotes(noteArray);
for(Note i : noteArray){
System.out.println(i);
}
}
private static void playNote() {
int numberDuration = Note.getduration();
String letterPitch = Note.getpitch();
System.out.println("The note "+ letterPitch +" is played for "+
numberDuration +" seconds.");
return;
}
public static void processNotes(Note[] notes) {
playNote();
}
}
class Note
{
private static String pitch;
private static int duration;
public Note(int duration, String pitch) {
this.pitch = "C";
this.duration = 10;
}
public static int getduration() {
return duration;
}
public void setduration(int duration) {
Note.duration = duration;
}
public static String getpitch() {
return pitch;
}
public void setpitch(String pitch) {
Note.pitch = pitch;
}
}
EDIT:
Output I would like:
The note C is played for 10 seconds.
Output of arrays I get:
Note#6d06d69c
Note#7852e922
Note#4e25154f
Note#70dea4e
Note#5c647e05
You have two possibility.
First, override your toString() method so that it prints your notes as you want when you System.out.println().
Second, you can in your loop, instead of printing the note :
for(Note i : noteArray){
System.out.println(i.getPitch());
System.out.println(i.getDuration());
}
Add the following to your Note class:
public String toString() {
return "Duration = " + duration + ", pitch = " + pitch;
}
Demo
From object.toString:
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.
The toString method for class Object returns a string consisting of
the name of the class of which the object is an instance, the at-sign
character `#', and the unsigned hexadecimal representation of the hash
code of the object. In other words, this method returns a string equal
to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
You can override this method for a more meaningful output.
Suggested further read: The connection between 'System.out.println()' and 'toString()' in Java
You can just override toString method of the Note class, as sysout implicitly call toString.

How to traverse through HashSet of objects and print the String value of each object in ToString method?

HashSet<Soldier> soldiers; // it has name, rank, description
#Override
public String toString(){
return "Team: " + teamName + "\n" + "Rank: " + getRanking(soldiers) + "\n"
+ "Team Members Names are: "+"\n" + soldiers.iterator().hasNext();
//last line doesn't work
// I also tried soldiers.forEach(System.out::println) but doesn't work
}
Can anyone please how I can print all the name from Hashset in overriden toString method. Thanks
If you use java 8. It's simple to do with stream API:
public class Test {
public static void main(String[] args) {
Set<String> strings = new HashSet<>();
strings.add("111");
strings.add("113");
strings.add("112");
strings.add("114");
String contactString = strings.stream().map(String::toString).collect(Collectors.joining(","));
}
}
If you want change a delimiter you should replace Collectiors.joining(",") code to what you need. See also documentation by StringJoiner
For your class Soldier which has method getName():
Set<Soldier> soldiers = new HashSet<>();
String soldierNames = soldiers.stream().map(Soldier::getName).collect(Collectors.joining("\n"));
You will get a next result:
Din
Mark
David
... values from the soldiers set
hasNext() does only return a boolean indicating if the Iterator is finished or not.
You still have to call next() (in a loop) to get the next value(s).
See: https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html

Print Array of Objects in BlueJ [duplicate]

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 6 years ago.
For an assignment, I was asked to work on calling a class and creating an array objects, which i did here;
public void DVDArrayObjects() {
//creates variables
int i;
DVDClass[] dvdArray = new DVDClass[5];
//reference to DVDClass
for (i = 0; i < 2; i ++) {
//create new instance of calling the class
dvdArray[i] = new DVDClass();
//create new instance of getting the info
dvdArray[i].getDVDInfo();
//display
//System.out.println(dvdArray[i]);
}
}
Creating the array of objects works fine, but displaying doesn't. it shows the memory allocation when i run it. I'm really stuck as to how to get it to display.
** EDIT **
When i use System.out.println(dvdArray[i].getDVDInfo()); the error void types not allowed in here shows up
** END OF EDIT **
Any help at all would be greatly appreciated.
Print the DVD info (assuming that it returns a string).
System.out.println(dvdArray[i].getDVDInfo());
If it doesn't return a string, you need to override the toString() method on the class DVDInfo like this.
#Override
public String toString()
{
return "Film Name\t: " + filmName +
"\nFilm Director\t: " + filmDirector +
"\nRun Time\t: " + runTime +
"\nLead Actor\t: " + leadActor;
}
Hope this helps.
You need to override the toString() method.
public class DVDCLass {
#Override
public String toString(){
return // whatever you want the output to be
}
}
Override toString() method in your DVDClass class
do like below
class DVDClass{
public String toString(){
return // whatever you want the output to be
}
}

android/java concept to call all getter methods with a single loop

I am doing an assignment and stuck at this point:
I have a class in which i have 30 getter and setter method.
public class example{
public String get1(){
return someString1;
}
public String get2(){
return someString1;
}
public String get3(){
return someString4;
}
and so on...
public String get30(){
return someString30;
}
}
Now i want to call all getter method with a single loop like
for(int i= 1; i<=30;i++){
// String total = get1()+get2()+get3()...............
}
what should i do?
Edit: i did it using reflection :
http://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html
Thanks Ricky
The commented code is the only way to do that. But this is a symptom that your design is incorrect. Rather than having 30 properties of type String, you should certainly have one property of type String[] or List<String>.
Then you could do:
List<String> list = getListOfStrings();
StringBuilder builder = new StringBuilder();
for (String s : list) {
builder.append(s);
}
String concatenation = builder.toString();
If these are the standard accessors then better to go for List and do get(index)
else Reflection hack will help
public class Example{
private List<Integer> marks = new ArrayList<Integer>();
now loop
for(int i= 1; i<=30;i++){
total += marks.get(i);
}
Just override the toString() method in the example class like this:
#Override
public String toString() {
return someString1 + " " + someString2 + " " + someString3;
}
I did it using reflection :
http://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html

Categories