In our current chapter we are using arrays which I'm having some trouble creating a listing to be called upon from another class.
Goal: Display the parallel arrays from another class, this can be singular or in a group.
Question: Best or efficient way to call on a multi-parallel array with different data types?
Error: Starts with an illegal statement, as previously instructed here is the whole code, please ignore the loop display I was just testing to make sure the arrays were setup correctly.
Thanks Everyone, Yet again any assistance is much appreciated
import java.util.ArrayList;
public class Employee {
public static void main(String[] args) {
// create an array with employee number, first name, last name, wage, and Skill
int[] empID = {1001, 1002, 1003};
String[] firstName = {"Barry", "Bruce", "Selina"};
String[] lastName = {"Allen", "Wayne", "Kyle"};
double[] wage = {10.45, 22.50, 18.20};
String[] skill = {"Delivery Specialist", "Crime Prevention", "Feline Therapist"};
/*
for ( int i = 0; i < empID.length; i++ )
{
System.out.print( "Employee ID: " + empID[i] + "\n");
System.out.print( "First Name: " + firstName[i] + "\n");
System.out.print( "Last Name: " + lastName[i] + "\n");
System.out.print( "Hourly Wage: $" + wage[i] + "\n");
System.out.print( "Skill: " +skill[i] );
System.out.println("\n");
}
*/
//create an object to be called upon from another class
public ArrayList<int, String, String, double, String> getEmployee() {
ArrayList<int, String, String, double, String> employeeList = new ArrayList<int, String, String, double, String>();
employeeList.add(empID);
employeeList.add(firstName);
employeeList.add(lastName);
employeeList.add(wage);
employeeList.add(skill);
return employeeList;
}
}
} //end of class
First, you can't declare an ArrayList like this:
ArrayList<int, String, String, double, String>
If you want that, you can create your own object, create a class which can take these values, then you can create an ArrayList of this Object for example:
class MyClass{
int att1;
String att2;
String att3;
double att4;
String att5;
public MyClass(int att1, String att2, String att3, double att4, String att5) {
this.att1 = att1;
this.att2 = att2;
this.att3 = att3;
this.att4 = att4;
this.att5 = att5;
}
}
Then you can create an ArrayList like this :
List<MyClass> list = new ArrayList<>();
Going back to the basics of Java, it is an object oriented programming language so you should always aim to abstract "things" into an object if possible. You should encapsulate all of the common properties about an 'employee' into a class with all of the data as fields.
As the answer above shows, creating an ArrayList<MyClass> is the proper way of initialising arraylists as they can only take ONE type of data. You may have seen other classes take multiple types such as HashMap<Type1, Type2> but these are for a specified reason. Make sure to check the API doc first!
Related
I am a java-noob as I recently started to learn in a course.
I have created a class:Humans which have ability to store their name and age, and also a subclass Students which extends Humans and adds the Year they began there studies.
I have constructed a randomHuman constructor where I call it(in my main class) and create a list with the humans(with random name and age).
My problem is when i want to random 5 human non-students and 5 students and create this list, I'm not sure how to find out what type of object is sent to the random constructor, so i know if i should give it a year or not. And what type to tell the constructor to return.
I am sorry that this turned into an essay, but if anyone would be so kind to help then I would greatly appreciate it.
TLDR; How to expand a randomHuman constructor to take two types of objects?
Here is my main class:
public class Main {
public static void main(String []args){
Human newHuman = new Human( 18, "Tommy");
System.out.println("Age: " + newHuman.getAge());
System.out.println("Name: " + newHuman.getName());
System.out.println(newHuman.toString());
Human putte = new Human (25,"Putte");
System.out.println(putte);
//Varför blir det så?
//kanske lokal variabel
//Array RandomHumans
System.out.println(" ");
System.out.println("Array Human");
ArrayList<Human> myAl = new ArrayList();
for(int i = 0; i<15; i++){
Human xx =Human.randomHuman();
myAl.add(xx);
}
//Array RandomFysiker
for(int j = 0; j<myAl.size(); j++){
Human var = myAl.get(j);
System.out.println(var.toString());
}
System.out.println(" ");
System.out.println("Array Fysiker");
ArrayList<Fysiker> myAl2 = new ArrayList();
//puts the Fysiker in an array
for(int i = 0; i<15; i++){
Fysiker xx =Fysiker.randomHuman();
myAl2.add(xx);
}
//prints teh array
for(int j = 0; j<myAl2.size(); j++){
Fysiker var = myAl2.get(j);
System.out.println(var.toString());
}
}
}
and my Human class:
public class Human {
public String name;
public int age;
Human(int ageIn, String nameIn){ //Constructor
age=ageIn;
name=nameIn;
}
public int getAge(){
return age;
}
public String getName(){
return name;
}
public String toString(){
return "Name: " + getName() +"," + " Age: " + getAge();
}
//Random human
// Behöver ändra konstruktorn så att den kan kolla
// om objectet är Fysiker eller Human och sedan,
// Behandla dom olika
//Problem1: Hur kollar man? Föreslag if(obj instanceof Fysiker), men vad ska jag ha som obj
//Problem2: Vilken returtyp ska man då ha?
public static Human randomHuman(){
String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"};
int randomAge = (int) (100*Math.random());
String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)];
int RandomYear = (int) (Math.random()*(2013-1932) + 1932);
// if(xx instanceof Fysiker){
//
// }
return new Human(randomAge,randomName);
}
}
and the subclass Fysiker(aka student):
/**
*
* #author Julian
*/
public class Fysiker extends Human{
public int schoolYear;
public Fysiker(int startYear,int ageIn, String nameIn){
super(ageIn, nameIn);
if (age>15){
if (startYear>2013){
} else if (startYear<1932){
} else {
schoolYear = startYear;
}
} else {
}
}
public int getYear(){
return schoolYear;
}
public String toString(){
return super.toString() +","+" Startyear: " +getYear();
}
}
Actually, your randomHuman() method, as mentioned in the comments, is not a constructor at all. It's a static factory method, although I'm sure you're not aware of what that means as yet.
Basically, a constructor is not a method at all and doesn't have a return type. What a constructor does is provide an initialization for a new instance of the class, created by using new, although it can do things that don't strictly initiate the fields of that object.
A method, in contrast, can return something. And in your particular case, the last line actually tells you exactly what it returns - it's calling new for the class Human, so it will return an object of class Human, never a Student.
In fact, the class Human is not aware of the class Student. In principle, you could write a subclass for a class, years after the parent class has been written. Parent classes don't need to know about their descendents. They just decide what they allow those descendents to change and what they don't allow them to change.
You could, in theory, put a method in Human that creates a Student instance. But I'm pretty sure that's not needed in the current situation.
What you probably want to do is fill a list of humans outside the definition of either Human or Student. Filling a random list is probably not part of "being a human" or "being a student" is all about, so you should just do it in your Main class, calling new Human() or new Student() as you wish and filling them as appropriate. Since you know which new you called, you also know whether or not to use a random year.
You could do it in a static method in your Main class, to signify that this is something you do for testing, and not really part of the logic of either a Human or a Student.
As for being able to tell which object you now got from the list - you can do that with instanceof. But you'll also need to typecast it to Student if you want to access its getYear() method.
However - and this is the neat thing about polymorphism - if you just call the toString() method, and don't even check the type of the object, you'll get it with the year if it's really a Student object, and without it if it's a plain Human object.
Let's assume your teachers actually want you to extend the randomHuman method so that it sometimes gives Human instances, and sometimes Students. When it gives Student, it should of course provide it with a year.
As I said above, this is called Tight Coupling between parent and subclass, and is not recommended. If I wanted to build another human subclass, such as Politician, I'd have to call you and ask you to release a new version of Human that also sometimes gives random Politicians. So, under protest, I'll explain how to do it.
Your existing function is:
public static Human randomHuman(){
String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"};
int randomAge = (int) (100*Math.random());
String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)];
int RandomYear = (int) (Math.random()*(2013-1932) + 1932);
// if(xx instanceof Fysiker){
//
// }
return new Human(randomAge,randomName);
}
We change it like so:
public static Human randomHuman(){
String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"};
int randomAge = (int) (100*Math.random());
String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)];
Human result = null;
if ( Math.random() < 0.5 ) {
// With a probability of 50%, create a plain human
result = new Human( randomAge, randomName );
} else {
// Create a student. Start by calculating a random year.
int randomYear = (int) (Math.random()*(2013-1932) + 1932);
result = new Fysiker( randomYear, randomAge, randomName );
}
return result;
}
So, you decide that you want to make a plain human, and within the scope of that decision, you create it with new Human(...) and assign to the result variable.
If you decide to make a student, within the scope of that decision, you calculate a random year, and create it with new Fysiker(). You can assign it to the variable result because polymorphically, it's Human. But in reality, internally, it's a Student.
You return the result variable, which may contain either a Human or a Student at this point.
For determining what type the object instance is use either object instanceof class or object.getClass().equals(Clazz.getSimpleName())
For return type just use the superClass (or interface). You can always cast it to the child if needed.
If you want to create 5 class of each you need a boolean in the method declaration and call it 5 times each to be sure u will have 5 instances of each class.
public static Human randomHuman(boolean isHuman){
If this is not important u can add a random boolean and then call the constructor:
boolean isHuman = Math.random() < 0.5;
if(!isHuman){
int RandomYear = (int) (Math.random()*(2013-1932) + 1932);
// create student
} else {
// create human
}
Ok, now I think I've given up all hope of finding solution to what should to be a simple problem. Basically, I'm creating a students' record system that stores students' details in an ArrayList. I first created a constructor in the Student class to specify what entries each student will have. I then created an instance of the Student class in the main class (i.e. class with the main method) and then added the student object to the studentList ArrayList.
By the way, instead of hard-coding the student details, my initial aim was to let the user enter the details and then I'll use a Scanner or BufferedReader object to get the details stored in the Student object, and then to the ArrayList but I'm having trouble with that as well; so I'll probably tackle that problem as soon as I'm done with this one.
Anyway, I'm expecting the output to print out the students' details but instead I get a memory location (i.e. [studentrecordsys.Student#15c7850]). I'm aware that I need to override the toString method but how exactly this is done is what I can't seem to get. I get syntax errors everywhere as soon as I enter the #Override code block for the toString method. Here's what I've tried:
import java.util.*;
class Student {
private String studentID;
private String studentName;
private String studentAddress;
private String studentMajor;
private int studentAge;
private double studentGPA;
Student (String studentID, String studentName, String studentAddress, String
studentMajor, int studentAge, double studentGPA){
this.studentID=studentID;
this.studentName=studentName;
this.studentAddress=studentAddress;
this.studentMajor=studentMajor;
this.studentAge=studentAge;
this.studentGPA=studentGPA;
}
}
public static void main(String[] args) {
Student ali = new Student("A0123", "Ali", "13 Bond Street", "BSc Software Engineering", 22, 3.79);
List<Student> studentList = new ArrayList<>();
studentList.add(ali);
#Override
String toString() {
StringBuilder builder = new StringBuilder();
builder.append(ali).append(studentList);
return builder.toString();
}
System.out.println(builder);
}
You need to implement the toString() on the Student object.
public class Student {
...
Your existing code
...
#Override
public String toString() {
return studentID + ", " + studentName + ", " + //The remaining fields
}
}
then in your main method, call
for (Student student : studentList) {
System.out.println(student.toString());
}
You to override toString method because it is going to give you clear information about the object in readable format that you can understand.
The merit about overriding toString:
Help the programmer for logging and debugging of Java program
Since toString is defined in java.lang.Object and does not give valuable information, so it is
good practice to override it for subclasses.
Source and Read more about overriding toString
public String toString() {
return "Studnet ID: " + this.studentID + ", Student Name:"
+ this.studentName+ ", Studnet Address: " + this.studentAddress
+ "Major" + this.studentMajor + "Age" + this.studentAge
+ GPA" + this.studentGPA ;
}
You get errors because you have to Override the toString method inside the class you want to use it for. i.e you have to put the method, with the #Override inside your Student class.
And you can call it like this:
System.out.println(studentA.toString());
System.out.println(studentB.toString());
or in a loop:
for(Student x : studentList)
System.out.println(x.toString());
and so on..
Also, in your code you create a method inside your main method. Of course you will get errors.
I am writing an airline program that will allow the user to input names and meal choice for each seating section economy, business, and first. I am trying to save all the names and meals into an array. but I am getting a syntax error.
I get expected message when I implement my flyer array.
I have looked on stack overflow. From what I can tell it should be ok to initialize my array this way.
Thanks for any help.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Flyers
{
public Flyers()
{
}
public List<String> seat = new ArrayList<>();
int numberOfFlyers;
int numberOfMeals;
String name;
String meal;
String[][] flyer;
public void addEconomyFlyer()
{
Scanner in = new Scanner(System.in);
System.out.print("Enter number of economy seats sold: ");
numberOfFlyers = in.nextInt();
flyer = new [numberOfFlyers][numberOfFlyers];
}
}
I want each [][] to have the same number of items that is equal to the number of people on the plane. Then I will add a nested for loop that will add a name for each of the flyers, and a meal choice. ultimately i need to be able to print out the array Name and their Meal choice.
Almost, the issue here is you haven't specified a type for the array.
flyer = new [numberOfFlyers][numberOfFlyers];
should probably be
flyer = new String[numberOfFlyers][numberOfFlyers];
However that doesn't make a lot sense. One solution is to use,
flyer = new String[numberOfFlyers][2];
where 0 is name and 1 is meal. But, really you should probably have a flyer POJO,
flyer = new Flyer[numberOfFlyers];
Where Flyer might look something like,
class Flyer {
Flyer(String name, String mealType) {
this.name = name;
this.mealType = mealType;
}
String name;
String mealType;
public String toString() {
return "Name: " + name + ", Meal: " + mealType;
}
}
Then you can create new Flyer(s) and call toString() in your loop. You might also choose to add getter and setter functions for name and mealType.
change :
flyer = new [numberOfFlyers][numberOfFlyers];
to:
flyer = new String[numberOfFlyers][numberOfFlyers];
Scanner class
Scan.scanner.scan
You need scan it!!!!
identifier = here
This trickes computer in think identifier there! YES! WORK!
I am trying to get this program to get the passwords from an array list.
import java.util.ArrayList;
public class CompanyDatabase {
public ArrayList<Person> getPeople() {
ArrayList<Person> people = new ArrayList<Person>();
String[] u = {"Joe","Stan","Leo","John","Sara","Lauren"};
String[] p = {"pass4321", "asdfjkl", "genericpw", "13579", "helloworld", "companypass"};
for(int j = 0; j < u.length; j++){
Person temp = new Person(u[j],p[j]);
people.add(temp);
}
return people;
}
}
import java.util.ArrayList;
import java.util.Scanner;
public class CompanyDatabaseDriver {
private static Scanner scan = new Scanner( System.in ) );
public static void main(String args[]) {
CompanyDatabase bcData = new CompanyDatabase();
ArrayList<Person> people = bcData.getPeople();
// what i tried
System.out.println(bcData.getPeople());
// also tried this
System.out.println(people.get(1));
}
}
The output is
[Person#1c9b9ca, Person#c4aad3, Person#1ab28fe, Person#105738, Person#ce5b1c, Person#1bfc93a]
or just
Person#1995d80
for the 2nd thing I tried.
The specific number / letter combination seems to change each time the program is run. Is there a way to specify which string to display from the array list?
Override toString() in the Person class
What you are seeing is the String returned by Object's default toString() method which is the name of the class followed by its hashcode. You will want to override this method and give the Person class a decent toString() method override.
e.g.,
// assuming Person has a name and a password field
#Override
public String toString() {
return name + ": " + password; // + other field contents?
}
Edit: if you only want to display one field in your output, then use Dave Newton's good solution (1+).
Yes; print the object property you want to see:
out.println(people.get(0).getFirstName());
the default implementation when you print List is to call toString for all objects in this List. and because you don't override toString method, it will call the default toString from Object class, that will print objects hashCode in hexadecimal notation, so you get this result:
Person#1c9b9ca ( classname#hashcode) , and it can be changed every time you execute the application because this hashcode come from memory address of the object).
so one option, is to override toString in your class
#Override
public String toString() {
return String.format("First name %s, Last name %s", firstName, lastName);
}
and call
System.out.println(yourList); // this will print toString for each object
the other option, is to print these attributes when you iterate on the List
for(Person person: persons) {
System.out.println("Person first name: " + person.getFirstName() + " , Last Name: " + person.getLastName());
}
In the first print statement you are trying to print the object..that is why you always see different number/letter combination..
Can Any help me and Check my answer
(a) Declare a private instance variable (Attribute) called HouseMap which should hold an unsorted map with integer keys and string values.
Private Map< Integer, String> HouseMap = new HashMap<Integer, String>();
(b) Write a zero-argument constructor of HouseCatalogue that initializes HouseMap to an empty map.
houseMap = new HashMap<Integer, String>();
(c) Write an instance method called addHouse() for the HouseCatalogue class that takes no arguments, and returns no value. This method should simply enter the four entries shown above into the HouseMap.
Public void addHouse()
{
HouseMap.put(101," adison Sas") ;
HouseMap.put(103," FourSeasons") ;
HouseMap.put(105," Hayat Regency ");
HouseMap.put(107," Concord al-Salam ") ;
}
(d) Write an instance method called printHouse() for the HouseCatalogue class that takes an integer argument, and return a string value. This method should print the value (House name) of the area code that is equal to integer argument and return it. Otherwise it will return null.
Public string printHouse( int area)
{
for(Integer eachcode : HouseMap.keySet())
{
if ( HouseMap.keySet()== area)
{
System.out.println("House name is"+ HouseMap.get(eachcode));
}
}
}
or
public static void printHouse( int area)
{
for(Map.Entry<Integer,String> entry : houseMap.entrySet())
{
if (entry.getKey().equals(area))
{
System.out.println("House name is"+ entry.getValue());
//return entry.getValue(); // return it
}
}
}
(a) Lower case letter for private and no new HashMap() needed when declaring. Normally when useing java convensions you use camelcase when declaring your variasbles (houseMap) but it's fine.
private Map<Integer, String> HouseMap;
(b) You have declared your variable with HouseMap not houseMap (see (a) camelcase) so initializing it needs the same variable:
HouseMap = new HashMap<Integer, String>();
(c) Seems fine
(d) Hum, don't see the point in the method, it should both print the value and return it.. well.. first off public lower case letters again, String with a big letter (name of the class` and then the implementation:
public String printHouse(int area) {
if (HouseMap.containsKey(area)) {
String name = HouseMap.get(area);
System.out.println("The house with the area code " + area +
" is " + name));
return name;
}
return null;
}
a) only declare the variable - do not initialize it
b) ok
c) ok
d) in a map you have random access. look at Map#get(Integer) API. you don't need to iterate over the entry set
Since the key of a map is unique, you can simplify the last method as follows:
public static void printHouse( int area)
{
String name = houseMap.get(area); // May return null
System.out.println("House name is " + name);
return name;
}
public and private must be written with a lowercase p everywhere.
You should show the entire constructor, not just the code that goes in it.
Fix your indentation. Use the same amount of indentation for every level, and make sure that everything lines up neatly.
When you use a foreach loop like for (Integer eachcode: HouseMap.keySet()), the iteration variable is eachcode. This is the value that you should compare to area, because that's what the integer is. You don't want to compare the supplied to all of the area codes taken as a single unit (those aren't the same kind of thing); you want to compare it to each area code in turn.
But you don't want to write that loop at all. The point of a HashMap is to let you look up the value, given the key. That is what .get() does. You have the key: it is area. So all you need to do is look it up: System.out.println("House name is " + HouseMap.get(area)).
You also need to return the name that you looked up, not just print it, and you need to check that the name is there (use .contains()) before printing.
It looks like somebody else commented your code to say "you also forgot to return it". Did you try talking to this person, or reading the comments?
Just a hint for the last one:
(d) Write an instance method called
An instance method is not a static method, you have to remove the static keyword in your second (d) method...
Thanks alot for every body
public static String printHouse(int
code) {
if (houseMap.containsKey(code))
{
String name = houseMap.get(coe);
System.out.println(code+ " : " + name);
return name;
} else{
System.out.println("null");
return null; }