I'm new in Java :] and I have a little problem with my app:
Why when I run it, it keeps saying me "null" even when person.setname("John")
I tried to fix it but without good result, what is wrong here and why?
I tried to debug it - same result - setName set name to John but anyway it keeps printing "null"
Really strange for new user like me.
If someone can help, or even try to say me what's wrong i'd be glad, thanks.
class App {
public static void main(String[] args) throws InterruptedException {
List<String> blacklist = Arrays.asList("Bill, Adam, Jessie");
;
Person person = new PersonWithBlacklistedCheck(
new PersonWithNullCheck(new Person()),
blacklist);
person.setName("John");
System.out.println("Person: " + person);
}
}
class PersonWithBlacklistedCheck extends Person {
private final List<String> blacklist;
private final Person target;
PersonWithBlacklistedCheck(Person target, List<String> blacklist) {
this.target = target;
this.blacklist = blacklist;
}
#Override
public String getName() {
return target.getName();
}
#Override
public void setName(String name) {
if (this.blacklist.contains(name)) {
throw new RuntimeException("[" + name + "] cannot be used as a name! it is blacklisted");
}
target.setName(name);
}
}
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class PersonWithNullCheck extends Person {
private final Person target;
PersonWithNullCheck(Person target) {
this.target = target;
}
#Override
public String getName() {
return target.getName();
}
#Override
public void setName(String name) {
if (name == null) {
throw new RuntimeException("[name] must not be null!!");
}
target.setName(name);
}
}
You have person object containing another person called "target" and another one "target" :
Blacklist should look like this:
List<String> blacklist = Arrays.asList("Bill", "Adam", "Jessie");
You were creating one entry: "Bill, Adam, Jessie".
You were doing some unnecessary metods override, adding unnecessary objects - when you extend class you have that object "person" already there, you don't need to put it as another object "target". If you want to have both null check and blacklist check executed before setting name you can extend classes in hierarchy: Person -> PersonWithNullCheck -> PersonWithBlacklistedCheck. Now setName() method will be executed in each of classes as ordered. Here's a fixed solution:
public class Test {
public static void main(String[] args) {
List<String> blacklist = Arrays.asList("Bill", "Adam", "Jessie");
Person person = new PersonWithBlacklistedCheck(blacklist);
person.setName("John");
System.out.println("Person: " + person);
}
}
class PersonWithBlacklistedCheck extends PersonWithNullCheck {
private final List<String> blacklist;
PersonWithBlacklistedCheck(List<String> blacklist) {
this.blacklist = blacklist;
}
#Override
public void setName(String name) {
if (this.blacklist.contains(name)) {
throw new RuntimeException("[" + name + "] cannot be used as a name! it is blacklisted");
}
super.setName(name);
}
}
class PersonWithNullCheck extends Person {
#Override
public void setName(String name) {
if (name == null) {
throw new RuntimeException("[name] must not be null!!");
}
super.setName(name);
}
}
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
Related
I got 2 classes
class Curso{
private String name;
public Curso(String nome){
this.name = nome;
}
public String getName(){
return this.name;
}
}
and
public class testaCurso{
public static void main(String[] args){
Course c1 = new Course("Computer Science");
c1.addDisciplina("AlgProgII");
c1.addDisciplina("SO");
c1.addDisciplina ("Grafos");
System.out.println(c1);
}
}
i gotta modify the Course class so that it can store the names of the Disciplina that make up the course and work for the test above with the output as shown. Consider that a course will not have a maximum of 50 subjects.
output:
Course: Computer Science,
Disciplinas:{ AlgProgII SO Grafos }
class Curso {
private String name;
// Add an list field containg the disciplinas
private final List<String> disciplinas = new ArrayList<>();
public Curso(String name){
this.name = name;
}
public String getName(){
return this.name;
}
// Add a `addDisciplina` method
public void addDisciplina(String name) {
disciplinas.add(name);
}
// Override the `toString` method
#Override
public String toString() {
return "Course: " + name + ", Disciplinas: + ", disciplinas;
}
}
We can implement toString() like the following:
public class Course {
private final String name;
private final List<String> disciplinas;
public Course(String name){
this.name = name;
this.disciplinas = new ArrayList<>();
}
public Course(String name, List<String> disciplinas){
this.name = name;
this.disciplinas = new ArrayList<>(disciplinas);
}
public void addDisciplinas(String discplina){
this.disciplinas.add(discplina);
}
#Override
public String toString() {
return "Course: " + name + ", Disciplinas: {" + disciplinas.stream().collect(Collectors.joining(" ")) +"}";
}
}
Usage:
Course course = new Course("Computer Science", Arrays.asList("AlgProgII", "SO", "Grafos"));
System.out.println(course);
Output:
Course: Computer Science, Disciplinas: {AlgProgII SO Grafos}
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 4 years ago.
i want to print all elements of my array list. Eclipse does not show an error, but it doesnt show the elements that i added in console. Can you please tell me what i did wrong?
The console shows:
Typ:Droide
ID:8282
NameR2D2
HumanoiderRoboter#15db9742
HumanoiderRoboter#6d06d69c
HumanoiderRoboter#7852e922
HumanoiderRoboter#4e25154f
Roboter Class:
public class Roboter {
protected String Name;
protected int ID;
protected String typ;
public Roboter(String Name, int ID, String typ) {
super();
this.Name = Name;
this.ID = ID;
this.typ = typ;
}
public void ausgebenNeu() {
System.out.println("ID:"+ID);
System.out.println("Name:"+Name);
System.out.println("Typ:"+typ);
}
HumanoiderRoboter Class:
import java.util.ArrayList;
public class HumanoiderRoboter extends Roboter {
String RoboterTyp;
public HumanoiderRoboter (String Name, int ID, String typ) {
super(Name, ID, typ);
}
public void ausgeben() {
ArrayList<HumanoiderRoboter> Sensoren = new ArrayList<HumanoiderRoboter>();
Sensoren.add(new HumanoiderRoboter("Sensor1", 4232, "Infrarotsensor"));
Sensoren.add(new HumanoiderRoboter("Sensor2", 9232, "Lichtsensor"));
Sensoren.add(new HumanoiderRoboter("Sensor3", 5777, "Touchssensor"));
Sensoren.add(new HumanoiderRoboter("Sensor4", 3321, "Gyrosensor"));
System.out.println("Typ:" + typ);
System.out.println("ID:" + ID);
System.out.println("Name" + Name);
for (Roboter ele : Sensoren) {
System.out.println(ele);
}
}
public static void main(String[] args) {
HumanoiderRoboter R2 = new HumanoiderRoboter("R2D2", 8282, "Droide");
R2.ausgeben();
}
}
Currently your problem is the HumanoiderRoboter doesn't overwrite the toString method which results the HumanoiderRoboter#4e25154f stuff. So if you overwrite the toString method it will print your object stuff you put in there:
...
#Override
public String toString() {
return "Typ: " + type + ", ID: " + id + ", Name: " + name;
}
...
Default toString method from Object looks like that:
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
So now if you do System.out.println(theObject) it will for example result something like this:
Typ: some, ID: 5, Name: NiceRoboter
And if you want the complete array as one String you can use the Arrays#toString method:
System.out.println(Arrays.toString(yourList.toArray()));
In your Roboter class override toString() method like this:
public class Roboter {
//-----member fields,methods
//Add this method
#Override
public String toString(){
return "{name:"+this.Name+"}";
}
}
Also read this link for naming convention to follow in Java https://www.geeksforgeeks.org/java-naming-conventions/
Override toString() method in Roboter class.
public class Test extends Roboter {
String RoboterTyp;
public Test(String Name, int ID, String typ) {
super(Name, ID, typ);
}
public void ausgeben() {
ArrayList<Test> Sensoren = new ArrayList<Test>();
Sensoren.add(new Test("Sensor1", 4232, "Infrarotsensor"));
Sensoren.add(new Test("Sensor2", 9232, "Lichtsensor"));
Sensoren.add(new Test("Sensor3", 5777, "Touchssensor"));
Sensoren.add(new Test("Sensor4", 3321, "Gyrosensor"));
System.out.println("Typ:" + typ);
System.out.println("ID:" + ID);
System.out.println("Name" + Name);
for (Roboter ele : Sensoren) {
System.out.println(ele);
}
}
public static void main(String[] args) {
Test R2 = new Test("R2D2", 8282, "Droide");
R2.ausgeben();
}
}
public class Roboter {
String Name;
int ID;
String typ;
public Roboter(String name, int iD, String typ) {
super();
Name = name;
ID = iD;
this.typ = typ;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getTyp() {
return typ;
}
public void setTyp(String typ) {
this.typ = typ;
}
#Override
public String toString() {
return "Roboter [Name=" + Name + ", ID=" + ID + ", typ=" + typ + "]";
}
}
This question was asked in my recent coding round. Its kind of tricky as we cannot modify getClass() and getClass().getName()
along with main method, Given are Food and FoodFactory class templates.
I had to print the following lines:
My name is Fastfood.
My name is Fruits.
Our superclass is Food
I'm serving Fastfood
I'm serving Fruit
Code:
/* Name of the class has to be "Main" only if the class is public. */
class FoodFactory{
public Food getFood(String string) {
// TODO Auto-generated method stub
return new Food(string);
}
public String toString(){
return "Food";
}
public static String getName(){
return "Food";
}
}
class Food{
String name;
public Food(String string) {
this.name = string;
}
public void servesFood() {
System.out.println("I'm serving "+name);
}
public String getName(){
return name;
}
}
class Solution
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
foodFactory myFoods = new foodFactory();
Food food1 = myFoods.getFood("Fastfood");
Food food2 = myFoods.getFood("Fruits");
System.out.println("My name is: " + food1.getClass().getName());
System.out.println("My name is: " + food2.getClass().getName());
System.out.println("Our superclass is: " + food1.getClass().getSuperclass().getName());
food1.servesFood();
food2.servesFood();
}
}
The key thing for this exercise is revealed by one word in your example output: superclass.
You want that getClass().getName() gives you different output. In order to get there, surprise: the objects you call getClass().getName() on ... need to have different classes!
Something like
class Food {
public void servesFood(){
System.out.println("I'm serving Food");
}
}
class FastFood extends Food {
#Override
public void servesFood(){
System.out.println("I'm serving Fastfood");
}
... similar for Fruit
If you now create instances of those two objects, they will give you the expected output. Now the question is: how are instances created?!
That is where your factory comes in:
class FoodFactory {
public Food getFood(String name) {
switch(name) {
case "FastFood" : return new Fastfood();
case "Fruit" : return new Fruit();
default: return new Food();
}
}
Please note: the above implementation assumes that any food that is not "Fastfood" or "Fruit"... is real "Food". And of course: you might expect that the actual "name" of the fruit ends up as some field within your Food class, but such refinements/extensions are left as exercise to the reader.
Here are the implementations of the two classes.
class FoodFactory{
private String name;
public Food getFood(String name){
this.name = name;
Food food = new Food(name);
return food;
}
public String getName{
return name;
}
}
class Food extends FoodFactory{
private String name;
public Food(String name){
this.name = name;
}
public void servesFood(){
System.out.println("I'm serving "+ name);
}
public String getName(){
return name;
}
}
This should work.
This one will work.
class FoodFactory extends Food {
public Food getFood(String string) {
if (string.equals("Fruit")) {
return new Fruit("Fruit");
} else {
return new FastFood("FastFood");
}
}
}
class Fruit extends Food {
public Fruit(String name1) {
super.name = name1;
}
}
class FastFood extends Food {
public FastFood(String name1) {
super.name = name1;
}
}
class Food {
public String name = null;
public Food() {
}
public Food(String string) {
this.name = string;
}
public void servesFood() {
System.out.println("I'm serving " + this.name);
}
}
class Solution1 {
public static void main(String[] args) throws java.lang.Exception {
FoodFactory myFoods = new FoodFactory();
Food food1 = myFoods.getFood("FastFood");
Food food2 = myFoods.getFood("Fruit");
System.out.println("My name is: " + food1.getClass().getName());
System.out.println("My name is: " + food2.getClass().getName());
System.out.println("Our superclass is: "
+ food1.getClass().getSuperclass().getName());// modification
food1.servesFood();
food2.servesFood();
}
}
I am trying to print the individual objects in the players class(performance, injured and name) and on the main class I am trying to print the entire player object however when I try executing the toString(); method on both classes, I just receive player#2eb3998c or Main#37e6e526. Where am I going wrong?
Thanks for any help.
Player class:
package com.laurens;
/**
* Created by laurensvanoorschot on 20-01-16.
*/
public class player {
private String name;
private int performance;
private boolean injured;
public player(int performance, boolean injured, String name) {
this.injured = injured;
this.name = name;
this.performance = performance;
}
public boolean isInjured() {
return injured;
}
public void setInjured(boolean injured) {
this.injured = injured;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPerformance() {
return performance;
}
public void setPerformance(int performance) {
this.performance = performance;
}
#Override
public String toString() {
return "com.laurens.player{" +
"injured=" + injured +
", name='" + name + '\'' +
", performance=" + performance +
'}';
}
}
main Class:
package com.laurens;
public class Main {
private player player;
public static void main(String[] args) {
player player = new player (4, true, "laurens");
player.toString();
}
public com.laurens.player getPlayer() {
return player;
}
#Override
public String toString() {
return super.toString();
}
public void setPlayer (int performance, String name) {
if (performance < 4) {
boolean injured = true;
}
}
}
Most likely, you simply forgot to recompile your classes; your Player code is fine (and you have errors in your Main class that you aren't aware of, which suggests no recompile). That said, there's nothing in your posted code that actually prints anything. System.out.println (actually, any PrintWriter print methods) will automatically call toString() on an object, so there's no need to do that yourself, just
System.out.println(player);
Use
System.out.println(player.toString());
toString() returns a string/textual representation of the object. How to use the toString method in Java?
Explicitly calling print, displays your properties fine:
System.out.println(player.toString());
as well as:
System.out.println(player);
What I'm trying to do works fine if I follow the JavaFX property definition described here.
Now, instead, I want to define properties from Java Beans objects using Java Beans Property Adapter. Since there is no documentation I can't figure out how it works.
Suppose I have a simple POJO class:
public class Person {
private String name;
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
and a PersonProperty:
public class PersonProperty {
private Person person = new Person();
private JavaBeanStringProperty name;
public PersonProperty() throws NoSuchMethodException {
name = JavaBeanStringPropertyBuilder.create().bean( person ).name( "name" ).build();
}
public Person getPerson() {
return person;
}
public void setPerson( Person person ) {
this.person = person;
}
public JavaBeanStringProperty nameProperty() {
return name;
}
}
and finally a test:
public void personTest() throws NoSuchMethodException {
PersonProperty pp = new PersonProperty();
pp.getPerson().setName( "A" );
pp.getPerson().setName( "B" );
pp.nameProperty().addListener( new ChangeListener<String>() {
#Override
public void changed( ObservableValue<? extends String> ov, String t, String t1 ) {
System.out.println( "from " + t + " to " + t1 );
}
} );
pp.getPerson().setName( "C" );
pp.getPerson().setName( "D" );
}
I'm expecting to see:
from B to C
from C to D
Instead nothing appears.
If I add pp.nameProperty().set("E") at the end of personTest I get from B to E
I think the issue here is that Person is indeed a POJO, but not a JavaBean: It is missing the hooks for PropertyChangeListeners. Java will not magically know when Person#name changes. Instead, the JavaFX adapter will look for a way to add a PropertyChangeListener and listen to events for a property called 'name'. If you add a PropertyChangeSupport instance to your Person class it will work as expected:
public class Person {
private String name;
private PropertyChangeSupport _changeSupport;
public Person() {
_changeSupport = new PropertyChangeSupport(this);
}
public String getName() {
return name;
}
public void setName( String name ) {
final String prev = this.name;
this.name = name;
_changeSupport.firePropertyChange("name", prev, name);
}
public void addPropertyChangeListener(final PropertyChangeListener listener) {
_changeSupport.addPropertyChangeListener(listener);
}
}