I'm trying to loop over an ArrayList object but I only get the following:
Name & Education:
com.company.Item#69d9c55
I have no clue why this is happening. I'm using the code provided in the MOOC course that I 'm following online, but am trying to redo this in my own small test project as I want to put what I learned into practice.
Here's the code:
Main
package com.company;
import java.util.Scanner;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// write your code here
Scanner scan = new Scanner(System.in);
ArrayList<Item> itemList = new ArrayList<>();
Item item;
while(true) {
System.out.println("Name plz?");
String name = scan.nextLine();
if (name.isEmpty()) {
break;
}
System.out.println("Education plz?");
String education = scan.nextLine();
if (education.isEmpty()) {
break;
}
item = new Item(name, education);
if (!itemList.contains(item)) {
itemList.add(item);
}
}
System.out.println("Name & Education: ");
for(Item detail : itemList) {
System.out.println(detail);
}
}
}
and the main Class
package com.company;
public class Item {
String name;
String education;
public Item(String name, String education) {
this.name = name;
this.education = education;
}
}
in your for loop you are printing the detail object.
for(Item detail : itemList) {
System.out.println(detail);
}
// prints
com.company.Item#69d9c55
first part is the package name (think folder sort of) and the random number after the # is an hashed value of the object. So basically a sort of short textual representation of the class.
there is two ways of fixing this:
adding getters to the object to fetch the values you want to print:
public class Item {
String name;
String education;
public Item(String name, String education) {
this.name = name;
this.education = education;
}
public String getName() {
return name;
}
public String getEducation() {
return education;
}
}
// Then in your loop fetch the values
for(Item detail : itemList) {
System.out.println(detail.getName());
System.out.println(detail.getEducation());
}
or the slightly more advanced version which is overriding the toString function in the object. Every object has a function called toString which prints per default the object hash. You can customize this by, naming a function toString and then annotation the function with #Override. Then in that function you can write a custom string that you want printed, when you try to print the object.
public class Item {
String name;
String education;
public Item(String name, String education) {
this.name = name;
this.education = education;
}
#Override
public String toString() {
return name + ", " + education;
}
}
in your for-loop while iterating over your Item list (maybe you should redefine your ArrayList using polymorphism) you will be getting each time an object item and not a detail, so choose the name of your execution variable right.
From this object item you should should whether call item.getName() or / and item.getEducation() if you haven't implemented or overriden a public String toString() method for your Item class or #Override public String toString() from the automatic inherited java.lang.Object class.
With that been said, let us fix and optimize your code:
Main.java
package com.company;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// write your code here
Scanner scan = new Scanner(System.in);
// Relying on the diamond operator
List<Item> itemList = new ArrayList<>();
Item item;
while(true) {
System.out.println("Name plz?");
String name = scan.nextLine();
if (name.isEmpty()) {
break;
}
System.out.println("Education plz?");
String education = scan.nextLine();
if (education.isEmpty()) {
break;
}
item = new Item(name, education);
if (!itemList.contains(item)) {
itemList.add(item);
}
}
System.out.println("Name & Education: ");
for(Item item : itemList) {
// Just call toString-method of Item class
System.out.println(item.toString());
}
}
}
Item.java
package com.company;
public class Item {
String name;
String education;
public Item(String name, String education) {
this.name = name;
this.education = education;
}
public String getName() {
return this.name;
}
public String getEducation() {
return this.education;
}
// you could also add some setters for these attributes if you need some later on
#Override
public String toString() {
return "[Name: " + this.name + ", Education: " + this.education + "]";
}
}
Hopefully, this will help you out. Also make sure you upvote the answer if it brings more details to you!
Related
import java.util.Arrays;
import java.util.Scanner;
public class employee{
public String name;
public class employee_address{
String street_name;
String city;
String zipcode;
String state;
String country;
}
public static void main(String []args){
Scanner user_input = new Scanner(System.in);
int no_of_employees = user_input.nextInt();
employee[] employees_list = new employee[no_of_employees];
for(int i = 0;i < no_of_employees;i++){
employees_list[i].name = user_input.nextLine();
employees_list[I].employee_address = // this is it ?
}
}
}
In the code above I do understand that the employee_address is a class and can't be accessed
directly without an instance being created like in the code, that makes no sense. but how can I create an instance of the employee_address class that is associate with each employee.
like in the code above 'employee_address' is associated with every employee but how can the class 'employee_address' be initialised and how can I set the street_name, city and the rest of the members in the address class. any ideas would be appreciated.
You can't directly create an instance of inner class, the reason because since it is the property of another instance we always need to use it though the instance of parent variable.
Let's say you have a class, which have two propeties:
public class Employee {
public String name;
public EmployeeAddress emAddress;
}
to access emAddress you need to use through the instance of Employee class, for example -
Employee object = new Employee();
EmployeeAddress empAdd = object.new EmployeeAddress();
Full code:
public class Employee {
public String name;
public EmployeeAddress emAddress;
public class EmployeeAddress {
String street_name;
String city;
String zipcode;
String state;
String country;
public String getStreet_name() {
return street_name;
}
public void setStreet_name(String street_name) {
this.street_name = street_name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Override
public String toString() {
return "EmployeeAddress [street_name=" + street_name + ", city=" + city + ", zipcode=" + zipcode
+ ", state=" + state + ", country=" + country + "]";
}
}
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
int no_of_employees = user_input.nextInt(); // let's say no_of_employees = 1
Employee[] employees = new Employee[no_of_employees];
for (int i = 0; i < no_of_employees; i++) {
Employee object = new Employee();
object.setName("Virat Kohli");
EmployeeAddress empAdd = object.new EmployeeAddress();
empAdd.setCity("New Delhi");
empAdd.setCountry("India");
empAdd.setState("Delhi");
empAdd.setStreet_name("Chandni Chalk");
empAdd.setZipcode("741124");
object.setEmAddress(emAddress);
employees[i] = object;
}
System.out.println(employees[0]);
user_input.close();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EmployeeAddress getEmAddress() {
return emAddress;
}
#Override
public String toString() {
return "Employee [name=" + name + ", emAddress=" + emAddress + "]";
}
public void setEmAddress(EmployeeAddress emAddress) {
this.emAddress = emAddress;
}
}
I have modified your code to sonar standard.
Below code uses Java naming conventions (which your code does not).
Notes after the code.
import java.util.Scanner;
public class Employee {
private String name;
private EmployeeAddress address;
public class EmployeeAddress {
String streetName;
String city;
String zipcode;
String state;
String country;
}
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
int noOfEmployees = userInput.nextInt();
Employee[] employeesList = new Employee[noOfEmployees];
for (int i = 0; i < noOfEmployees; i++) {
employeesList[i] = new Employee();
employeesList[i].name = userInput.nextLine();
EmployeeAddress employeeAddress = employeesList[i].new EmployeeAddress();
employeesList[i].address = employeeAddress;
employeesList[i].address.streetName = userInput.nextLine();
}
}
}
An inner class is a normal class. It is not a member of its enclosing class. If you want class Employee to have an [employee] address, as well as a [employee] name, you need to add another member variable to class Employee whose type is EmployeeAdress.
Employee[] employeesList = new Employee[noOfEmployees];
The above line creates an array but every element in the array is null. Hence you need to first create a Employee object and assign it to an element of the array. Hence the following line in my code, above:
employeesList[i] = new Employee();
Since EmployeeAddress is not a static class, in order to create a new instance, you first need an instance of the enclosing class, i.e. Employee. Hence the following line in the above code.
EmployeeAddress employeeAddress = employeesList[i].new EmployeeAddress();
Since all your code is in class Employee, in method main you can directly access the members of both class Employee and EmployeeAddress. Nonetheless you need to be aware of the different access modifiers in java.
A few hints:
stick to naming conventions: class names in Java start with capital letters
use (class) definitions before using them (collect them at the top if not inconventient)
if you are sure you want to use inner classes, set them static, unless you want them to be entangled in generics.
Usually normal classes in each their own file are a lot more flexible and far easier to use
if you use objects that only carry public data, try to use final keyword and initialize them ASAP
use proper objects first, and after finishing them assign them to arrays. avan better would be the use of ArrayList and the like
if Employee contains EmployeeAddress, it should initialize it if conventient. so an object is always responsible for its own stuff
Use try/resrouce/catch
scanner.nextInt() can be problematic with newline/line breaks. For user input better readLine() and parse input
Code:
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;
public class Employee {
static public class EmployeeAddress {
public final String street_name;
public final String city;
public final String zipcode;
public final String state;
public final String country;
public EmployeeAddress(final Scanner pScanner, final PrintStream pOutPS) {
street_name = readLine(pScanner, pOutPS, "Please enter Street Name:");
city = readLine(pScanner, pOutPS, "Please enter City Name:");
zipcode = readLine(pScanner, pOutPS, "Please enter Zip Code:");
state = readLine(pScanner, pOutPS, "Please enter State:");
country = readLine(pScanner, pOutPS, "Please enter Country:");
}
}
static public String readLine(final Scanner pScanner, final PrintStream pOutPS, final String pPrompt) {
pOutPS.print(pPrompt);
final String value = pScanner.nextLine();
pOutPS.println();
return value;
}
static public int readInt(final Scanner pScanner, final PrintStream pOutPS, final String pPrompt) {
return Integer.parseInt(readLine(pScanner, pOutPS, pPrompt));
}
public final String name;
public final EmployeeAddress address;
public Employee(final Scanner pScanner, final PrintStream pOutPS) {
name = readLine(pScanner, pOutPS, "Please enter Employee Name: ");
System.out.println("Name: " + name);
address = new EmployeeAddress(pScanner, pOutPS);
}
public static void main(final String[] args) {
try (final Scanner user_input = new Scanner(System.in);
final PrintStream output = System.out;) {
final int no_of_employees = readInt(user_input, output, "Please enter number of users: ");
final Employee[] employees_list = new Employee[no_of_employees]; // either this line
final ArrayList<Employee> employees = new ArrayList<>(); // or this line
for (int i = 0; i < no_of_employees; i++) {
output.println("Creating user #" + (i + 1) + "...");
final Employee newEmployeeWithAddress = new Employee(user_input, output);
employees_list[i] = newEmployeeWithAddress; // either this line
employees.add(newEmployeeWithAddress); // or this line
}
}
}
}
I'm a JAVA beginner.
I am trying to create a java phonebook which as three main classes
Contacts.java
Phonebook.java
Showphonebook.java
Contacts has two variables that are non-static, name and phone, which hold name and phone numbers of a person.
Then Phonebook is a class which holds the Phonebook objects and has a variable owner which is a string. So basically, the Phonebook object holds a owner and makes references to Contacts object to add contacts to it.
Then the final class Showphonebook is the class that makes a new Phonebook with owner and adds contacts to it.
Here is my code for above:
Contact.java
public class Contact {
private String name;
private String phone;
public Contact(String name, String phone) {
this.name = name;
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String toString() {
return name + ": " + phone;
}
}
Phonebook.java
import java.util.*;
public class Phonebook
{
private String owner;
public ArrayList<Contact> contacts = new ArrayList<Contact>();
public Phonebook(String owner) {
this.owner = owner;
}
public void addContact(Contact name) {
contacts.add(name);
}
public void show() {
System.out.println(owner + "'s phonebook");
for (Contact name : contacts) {
System.out.println(name);
}
}
/*public String findContactByName(String contactToSearch) {
for (Contact name : contacts) {
if (this.getName().equals(contactToSearch)) {
}
}
}*/
}
ShowPhonebook.java
public class ShowPhonebook
{
public static void main(String[] args) {
Phonebook phonebook1 = new Phonebook("Sam Johnson");
phonebook1.addContact(new Contact("Kelly Wong", "(02) 12345678"));
phonebook1.addContact(new Contact("Richard Jackson", "(02) 87654321"));
phonebook1.show();
}
}
I wanted to make a method in Phonebook.java which can SEARCH the phonebook to see if a contact exists , else return null.
How can I do this? I was thinking if I will use getName() method in Contact to pull out the NAME of each contact in the contacts ArrayList and compare it to the contactToSearch variable, but since getName() is non-static, how do I do it? I am confused because Contact holds the getName, but to reference that, I need an object, but my only object phonebook1 is in ShowPhonebook class, which I feel has to go through two classes to get there. Not sure how to do it.
Looking for guidance here!
First of all, welcome to stack overflow!
Now I'm assuming you are new to java hence confused about how references and this work in java. To get what you are asking, I would suggest following modification in the commented method-
public String findContactByName(String contactToSearch) {
for (Contact contact : this.contacts) { // changed "name" to "contact"; variable name should be aptly chosen
if (contact.getName().equals(contactToSearch)) {
// TODO: do your thing with "contact" variable
}
}
}
this refers to the current instance of the class. In your case, this will refer to the phonebook1 instance.
I have a String in this format (including curly brackets):
{id=123, vehicle_name=Tesla Model X, price=80000.00, ... }
What is the appropriate Java object to represent this String, and how can I convert it to that object?
I would like to be able to query the object to retrieve its values easily, eg. obj.get("vehicle_name"). I've tried converting it to JSON using JSONObject however this expects colons as the delimiters between keys and values, rather than the equals sign.
String itself is a java object.
Parsing String and filling up a java object is not clean.
You can create a java pojo Vehicle with attributeS like id,
vehicle_name etc. Assuming your String will always follow a same
pattern.
Parse the String, and fill this Vehicle pojo.
Below is just a simple example, on how to do it :-
public class Test {
public static void main(String[] args){
String text="{id=123, vehicle_name=Tesla Model X, price=80000.00}";
text=text.replaceAll("[{}]", "");
String[] commaDelimitArray=text.split(",");
Vehicle vehicle=new Vehicle();
for(int i=0;i<commaDelimitArray.length;i++){
String[] keyValuePair=commaDelimitArray[i].split("=");
String key=keyValuePair[0].trim();
String value=keyValuePair[1].trim();
if("id".equals(key)){
vehicle.setId(value);
}
else if("vehicle_name".equals(key)){
vehicle.setVehicleName(value);
}
else if("price".equals(key)){
vehicle.setPrice(value);
}
}
System.out.println(vehicle.getId()+" |"+vehicle.getVehicleName());
}
static class Vehicle{
private String id;
private String vehicleName;
private String price;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(String vehicleName) {
this.vehicleName = vehicleName;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
}
This appears to be an assignment in creating Object classes. If so, you want to create something like this:
public class Car {
int id;
String name;
double price;
//include any other necessary variables
public Car(int id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
//include any other variables in constructor header and body
}
public void setID(int newID) {
id = newID;
}
public int getID() {
return id;
}
//add getters and setters for other variables in this same manner
}
Note that you could alternatively create a constructor that takes no parameters and initializes variables to default values, then set the values individually using the setter methods.
In your main class, what you want to do is extract the appropriate substrings from your String to pass to the constructor (or setters). There are various ways of doing this (you can read about some ways here); I would personally recommend using regular expressions and a Matcher.
If I had such a string which needed to be converted to an object I would create a class with a static method which returns a Vehicle object. Then you can do whatever you want with that object. A few getters and setters and you should be good to go.
I have come up with some code which should work as you expect if I have understood your question :)
There is quite a few comments so this should help you understand the code logic.
The Vehicle Class is where all parsing happens in the static method named createVehicle(String keyValueString).
The main class:
import java.util.ArrayList;
import java.util.List;
public class main {
public static void main(String[] args) {
String vehicleString = "{id=123, vehicle_name=Tesla Model X, price=80000.00}";
List<Vehicle> vehicles = new ArrayList<Vehicle>();
Vehicle vehicle;
// call the static method passing the string for one vehicle
vehicle = Vehicle.createVehicle(vehicleString);
// if the id is -1, then the default constructor fired since
// there was an error when parsing the code.
if(vehicle.getId() == -1 ) {
System.out.println("Check your data buddy.");
} else {
vehicles.add(vehicle);
}
for(Vehicle v : vehicles){
System.out.println("Vehicle id: " + v.getId());
System.out.println("Vehicle name: " + v.getVehicle_name());
System.out.println("Vehicle price: " + v.getPrice());
System.out.println();
}
}
}
The Vehicle Class:
import java.math.BigDecimal;
public class Vehicle {
// declare your attributes mapped to your string
private int id;
private String vehicle_name;
private BigDecimal price;
// Start Constructor
// Default Constructor
public Vehicle() {
this.setId(-1);
this.setVehicle_name("Empty");
this.setPrice(new BigDecimal(0.00));
}
public Vehicle(int id, String vehicle_name, BigDecimal price) {
this.setId(id);
this.setVehicle_name(vehicle_name);
this.setPrice(price);
}
// End Constructor
// Start Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getVehicle_name() {
return vehicle_name;
}
public void setVehicle_name(String vehicle_name) {
this.vehicle_name = vehicle_name;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
// End Getters and Setters.
// Start Methods and Functions
// Given a string returns a string array split by a "," and with
// "{}" removed.
private static String[] splitString(String keyValueString) {
String[] split;
// Clean string from unwanted values
keyValueString = keyValueString.replaceAll("[{}]", "");
split = keyValueString.split(",");
return split;
}
// Add a vehicle given a formatted string with key value pairs
public static Vehicle createVehicle(String keyValueString) {
int id = 0;
String vehicle_name = "";
BigDecimal price = null;
String[] split;
Vehicle vehicle;
split = splitString(keyValueString);
// Loop through each keyValue array
for(String keyValueJoined : split){
// split the keyValue again using the "="
String[] keyValue = keyValueJoined.split("=");
// remove white space and add to a String variable
String key = keyValue[0].trim();
String value = keyValue[1].trim();
// check which attribute you currently have and add
// to the appropriate variable
switch(key){
case "id":
id = Integer.parseInt(value);
break;
case "vehicle_name":
vehicle_name = value;
break;
case "price":
try {
price = new BigDecimal(Double.parseDouble(value));
} catch (NumberFormatException e) {
e.printStackTrace();
}
break;
default:
System.out.println("Attribute not available");
return null;
}
}
// if any of the values have not been changed then either the
// data is incomplete or inconsistent so return the default constructor.
// Can be removed or changed if you expected incomplete data. It all
// depends how you would like to handle this.
if(id == 0 || vehicle_name.equals("") || price == null){
vehicle = new Vehicle();
} else {
//System.out.println(id);
vehicle = new Vehicle(id, vehicle_name, price);
}
return vehicle;
}
// End Methods and Functions
}
The program, given the string provided, returns the following when accessing the newly created object attributes using the getters:
Vehicle id: 123 Vehicle name: Tesla Model X Vehicle
price: 80000
Hope this helps.
I have an past exam question that says:
"Create a class Element that records the name of the element as a String and has a public method, toString that returns the String name. Define a constructor for the class (that should receive a String to initialise the name)."
I gave it a go and don't where to go from here...
main class is:
public class builder {
public static void main(String[] args) {
element builderObject = new element(elementName);
}
}
and constructor is:
import java.util.*;
class element {
public int getInt(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the first number");
String elementName = scan.nextLine();
System.out.println("%s");
}
public String toString() {
return elementName;
}
}
Don't get frustrated. Please read java tutorials first and understand the concepts. your exam question is very clear on what you need to do. Atleast for this question, you need to know what is constructor, the purpose of having toString() in a class.
May be the below can help you.
public class Element {
private String elementName;
public Element(String elementName) {
this.elementName = elementName;
}
#Override
public String toString() {
return elementName;
}
}
I can't think of a way to explain this without actually giving the answer, so....
public class Element { /// Create class Element
private final String name; // Record the 'name'
public Element(String name) { // constructor receives and sets the name
this.name = name;
}
public String toString() { // public method toString() returns the name
return name;
}
}
You are missing the constructor itself. The point of constructors is to initialize the object, usually by saving the given parameters to data members.
E.g.:
class Element {
/** A data member to save the Element's name */
private String elementName;
/** A constructor from an Element's name*/
public Element(String elementName) {
this.elementName = elementName;
}
#Override
public String toString() {
return elementName;
}
}
class Element {
private String name = "";
/**
/* Constructor
/**/
public void Element(final String name){
this.name = name;
}
#Override
public String toString(){
return name;
}
}
You don't have a constructor in there. A constructor typically looks something like this:
public class MyClass {
private String name;
private int age;
//This here is the constructor:
public MyClass(String name, int age) {
this.name = name;
this.age = age;
}
//here's a toString method just for demonstration
#Override
public String toString() {
return "Hello, my name is " + name + " and I am " + age + " years old!";
}
}
You should be able to use that as a guideline for making your own constructor.
class Element
{
private String name = "UNSET";
public String getName() { return name; }
public Element(String name) {
this.name = name;
}
public String toString() {
return getName();
}
}
You are missing a constructor you might be looking for something like this
public class Element{
private String name;
public Element(String name){ //Constructor is a method, having same name as class
this.name = name;
}
public String toString(){
return name;
}
}
A note
I take you are starting with java, In java class names usually start with capital letter, thus element should be Element. Its important that one picks up good habits early..
I am trying to construct a store by reading items from a given Scanner. The constructor must repeatedly (until item name is *) read items from the given scanner object and add it to its inventory.
BreadLoaf 2.75 25
I need to divide a string like this into "Breadloaf" "2.75", and "25". And then go to the next line and do the same thing until it reads "*"
public class Store {
private ArrayList<Item> inventory;
// CONSTRUCTORS
/*
* Constructs a store without any items in its inventory.
*/
public Store() {
}
/*
* Constructs a store by reading items from a given Scanner. The constructor
* must repeatedly (until item name is *) read items from the given scanner
* object and add it to its inventory. Here is an example of the data (that
* has three items) that could be entered for reading from the supplied
* scanner:
*/
public Store(Scanner keyboard) {
while(keyboard != null){
}
}
Try below code. it works I have recently checked.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class MyClient {
public static void main(String args[]) {
List<Item> inventory = new ArrayList<Item>();
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String s1 = sc.nextLine();
if (s1.equals("*")) {
break;
} else {
Scanner ls = new Scanner(s1);
while (ls.hasNext()) {
Item item = new Item(ls.next(), ls.nextFloat(), ls.nextInt());
inventory.add(item);
}
}
}
System.out.println(inventory);
}
}
Now you need to create an Item.java below is Item .java
public class Item {
private String name;
private int quanity;
private float price;
public Item(String name, float price, int quanity) {
this.name = name;
this.price = price;
this.quanity = quanity;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getQuanity() {
return quanity;
}
public void setQuanity(int quanity) {
this.quanity = quanity;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
#Override
public String toString() {
return "Item [name=" + name + ", quanity=" + quanity + ", price="
+ price + "]";
}
}
After typing all the inventory type "*"(star) at the end it will list all the entered Items .