Passing an object array to method - java

So I want to use a method to write multiple objects to respective files. However I do not know how to import the array of Objects without defining the specific Object.
The people is class is purely for storing the created objects in arrays so it is easier to access across other classes.
For example
public class People {
private Student[10];
private Teacher[10];
public void setStudentArray(Student, index) {
Student[index] = Student;
}
public void setTeacherArray(Teacher, index) {
Teacher[index] = Teacher;
}
}
public class Student extends People {
String name;
int StudentID;
public String getName() {
return name;
}
}
public class Teacher extends People {
String name ;
int Teacher ID;
public String getName() {
return name;
}
}
public class Main {
People p = new People();
public void main (String[] args) {
Student s = new Student("default-name" , 1);
p.setStudentArray(s, 0);
Teacher t = new Teacher("default-name", 1);
p.setTeacherArray(t, 0);
outputName(p.getStudentArray, 0);
outputName(p.getTeacherArray, 0)
}
//THIS IS WHERE I AM STRUGGLING I dont know how to pass teachers or students array to it.
//I want the Object[] parameter to accept both Student[] and Teacher[]
public void outputName(Object[], index) {
System.out.println(Object[index].getName);
}
}
I think that my Method taking an Object[] is wrong but I do not know how to approach it otherwise. I believe the issue is that Object[] is an entirely different class to Teacher[] and Student[] and this is where I am going wrong.
I want to use the .getName method in both the classes of Teacher and Student in order to print the name of the Teacher of Student. (Merely so I can see the passing is working.)
If this is just not possible I guess I will just not try a method that can take different objects.
I know that I can just use two methods one for students and one for teachers but I want the method to work for multiple objects so that I can add more object arrays to it.

So People class is extended by both Student and Teacher.
What commonalities are here?
String name is present in both Student and Teacher
public String getName() is also present in both Student and Teacher
You can move these commonalities to People class. Also ensure to remove the name attribute and getName from Student and Teacher class
So your People updated class can be:
public class People {
private String name; //Newly added
private Student[10]; //This ideally shouldn't be in People class rather a different class
private Teacher[10]; //This ideally shouldn't be in People class rather a different class
public void setStudentArray(Student, index) {
Student[index] = Student;
}
public void setTeacherArray(Teacher, index) {
Teacher[index] = Teacher;
}
public String getName() {
return name;
}
public void setName() {
this.name = name;
}
}
The outputname method should be like:
public void outputName(People[] people, index) {
System.out.println(people[index].getName());
}
NOTE: I am not correcting the syntax here, but just giving an idea.

What #Li357 said is right... You have to change your modeling a bit. Even if you managed to pass Student[] as an Object[], you wouldn’t be able to call the getName method as it’s not an Object method.
So a better modeling would be to make the getName method a People method, and both Student and Teacher classes would inherit it.
Then you could receive People[] as the outputName method argument, and use the getName method inside.

First of all learn how to declare array and choose valid variables.
In your People class do following modifications.
public class People {
//Declare arrays like this.
private Student[] student;
private Teacher[] teacher;
//Initialize arrays
public People(){
student = new Student[10];
teacher = new Teacher[10];
}
public void setStudentArray(Student s,int index) {
student[index] = s;
}
public void setTeacherArray(Teacher t, int index) {
teacher[index] = t;
}
//Add getter methods
public Student[] getStudentArray(){
return student;
}
public Teacher[] getTeacherArray(){
return teacher;
}
}
Inside sub classes Student and Teacher add Argument constructor
Finally in your outputName method you can do something like this.
public static void outputName(Object[] obj, int index) {
if(obj instanceof Student[]){
Student[] s = (Student[])obj;//parsing to student array
System.out.println("Student name : "+s[index].getName());
}
if(obj instanceof Teacher[]){
Teacher[] teacher = (Teacher[])obj;//parsing to teacher array
System.out.println("Teacher name : "+teacher[index].getName());
}
}
Output:
Student name : default-name
Teacher name : default-name

Related

java generic wildcard not working as expected

The code shown below was given to explain generic wildcard usage.
I have a Student parent class and Dayscholar child class. I have Record<Student> class that maintains a list of Student/Dayscholar objects and a method named display that accepts a parameter of Record<? extends Student> and displays the list. This works with either Record<Student> or Record<Dayscholar>. And according to what I understood from the course the wildcard is required. Meaning if declaration of display method is changed to display(Record<Student>) the method will not accept the parameter Record<Dayscholar> and will issue a compile time error.
But declaring display method as display(Record<Student> somename) worked just as fine with record of type Student or of type Dayscholar. I am confused. What would be best example to demonstrate generic wildcard?
class Record<Student>//<Number>
{
List<Student> record =new ArrayList<>();
#Override
public String toString() {
return "Record [record=" + record + "]";
}
public void add(Student e)
{
record.add(e);
}
public void display(Record< Student> record) {
System.out.println("student record:"+record);
}
}
class Student
{
int id;
String name;
public Student(int id,String name)
{
this.id=id;
this.name=name;
}
#Override
public String toString()
{
return "Id = "+id+" Name = "+name;
}
}
class Dayscholar extends Student
{
float stipend;
public Dayscholar(int id,String name,float stipend)
{
super(id,name);
this.stipend=stipend;
}
#Override
public String toString()
{
return "Id = "+id+" Name = "+name+" Stipend = "+stipend;
}
}
class WildcardsDemo
{
public static void main(String[] args)
{
Record<Student> studentrecord = new Record<>();
studentrecord.add(new Student(9999,"hassan"));
studentrecord.display(studentrecord);
Record<Dayscholar> dayscholar = new Record<>();
dayscholar.add(new Dayscholar(2222,"Sam",900));
dayscholar.display(dayscholar);
}
}
Everything in my post was correct until few hours ago (now it is 11pm US ET) when I ran the code/s again. I ran the code in play ground of training course and wild card proved to be holding to my surprise. I don't know how explain this. Is it my laptop / is it that the browser was caching previous good runs? I hope this will not be considered as a point against me.

How can I assign variables to my class constructor if they are static?

I'm running into a problem where I am using a method to take in user data and the method is to return an object. The problem is whenever I get to assigning the inputted values to the class constructor I am met with an error message stating, "non-static variable this cannot be referenced from a static context." I am aware that my methods are declared using public static [return value], which is ultimately leading to this issue. I have to keep the methods as static, though, as a part of this project. That leaves me somehow manipulating the class or class constructor, but I'm not certain as to how to do that.
This is the class and class constructor:
public class Project1 {
public class Student {
String name;
String ID;
float GPA;
int creditHours;
double tuitionCost;
public static Student (String name, String ID, float GPA, int creditHours, double tuitionCost) {
this.name = name;
this.ID = ID;
this.GPA = GPA;
this.creditHours = creditHours;
this.tuitionCost = tuitionCost;
}
}
This is how I am attempting to assign the user inputted data to the class constructor.
Student ret = new Student();
ret.name = name;
ret.ID = ID;
ret.GPA = GPA;
ret.creditHours = creditHours;
ret.tuitionCost = tuitionCost;
return ret;
How can I assign the values I have read in from the user (using Scanner) to the class constructor if the method in which they are read in is static?
Note: I'm new to Java, so some of my jargon may be a bit off.
static constructors are not allowed in Java
Then your Student class is not static, it means that it could be created only with parent Project1.
public class Project1 {
public class Student {
public Student() {
}
}
public static void main(String... args) {
Project1 project1 = new Project1();
Student student = project1.new Student();
}
}
You have to make Student class statis if you want to use Student class without Project1.
public class Project1 {
public static class Student {
public Student() {
}
}
public static void main(String... args) {
Student student = new Project1.Student();
}
}
The title of the question seems very simple but the description is quite confusing:
How can I assign variables to my class constructor if they are static?
As per my understanding, if you want to assign some static variables in your constructor then in the first place you should have static variables present in your class which seems to be missing.BUT there is something more which you are missing.
There are no static constructors in java, you might need to refer:
Why a constructor cannot be static or Can we define static constructors
I doubt the code snippet you posted would compile because the compiler should throw an error as you can never have a static constructor in a class.
Now coming to your actual issue:
How can I assign the values I have read in from the user (using Scanner) to the class constructor if the method in which they are read in is static?
I modified your code little bit to solve your issue:
package com.sopra.banking.compliance.report.backend.common.bean;
import java.util.Scanner;
public class Test
{
public static class Student
{
String name;
public Student()
{
}
public Student(String name)
{
Student student = readValues();
this.name = student.name;
}
static Student readValues()
{
Scanner sc = new Scanner(System.in);
Student student = new Student();
String name = sc.next();
student.name = name;
return student;
}
}
}
As a side note, you were having an inner class and if you want to define a static method in an inner class then you need to make that class as static.
Constructors cannot be static. Methods can.
If you need a static method that returns a Student, it would look like
public static Student buildStudent(String name, String ID, float GPA, int creditHours, double tuitionCost) {
Student ret = new Student();
ret.name = name;
ret.ID = ID;
ret.GPA = GPA;
ret.creditHours = creditHours;
ret.tuitionCost = tuitionCost;
return ret;
}
However, using an actual constructor is arguably more straightforward for object creation

creating map of values from object

we have
class Student
{
String name,
int age,
String specialization
}
and
class Students
{
List<String> names,
List<Integer> age,
List<String> specialization
}
Students object is basically a structure that holds field values of Student class,
What is the best way to fill Students object without using reflection.
Edit: we have a specific requirement of having Students class as it is, the reason for this is we don't always want all the information in Student class and if we have List it would allocate memory for the fields that we are not interested in.
Don't create class Students. Hold a list of Student
List<Student> students = new ArrayList<Student>();
And to access a student data you can use
students.get(0).name;
As a side note, you should learn about getters and setters.
I wouldn't recommend creating a class named "Students" for this purpose. Your intention is to create a collection to hold the Student objects.
In this case, do the following:
List<Student> students = new ArrayList();
Also, pay attention to the capitalization: class is a keyword and should be spelled all lower-case.
EDIT After seeing a comment from venkat:
If you really need to create a class called Students then following should work (also similar answer provided above by another SO user):
class Students {
List<Student> students = new ArrayList();
}
This should work, but I would highly recommend not to use these type of class with the plural names!
PS: I am a CS prof teaching programming languages in a university and a long time developer/consultant.
Class Students {
List<Student> students;
}
Maybe you want to use a Decorator-Pattern (I don't think that i saves memory):
Implement a base class with the default field:
public class BaseClass implements INameGettable {
protected String name;
public BaseClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Add the default interface:
public interface INameGettable {
String getName();
}
Add a decorator to for an additional field e.g. age:
public class Decorator implements INameGettable {
protected INameGettable nameable;
protected int age;
public Decorator(INameGettable nameable, int age) {
this.nameable = nameable;
this.age = age;
}
public String getName() {
return nameable.getName();
}
public int getAge() {
return this.age;
}
}
Usage:
// First object contains only name
INameable namegettable = new BaseClass("Test1");
namegettable.getName();
// Second object contains name and age
Decorator agegettable = new Decorator(new BaseClass("Test2"), 77);
agegettable.getName();
agegettable.getAge();
Going for the obvious answer here.
class Students
{
List<String> names;
List<Integer> age;
List<String> specialization;
public Student(List<Student> students) {
addStudents(students);
}
private void addStudents(List<Student> students) {
names = students.stream
.map(Student::getName)
.collect(Collectors.toList())
age = students.stream
.map(Student::getAge)
.collect(Collectors.toList())
specialization = students.stream
.map(Student::getSpecialization)
.collect(Collectors.toList())
}
}

Java - Abstract classes and concrete classes

I'm working on my assignment but I got confused with the abstract classes and concrete classes, and I get error from my program...
Suppose there is an abstract class Person and a concrete subclass Student:
abstract class Person{
private String name;
public Person(String s){
name = s;
}
public String getName() {
return name;
}
public abstract void doAction(Person other);
}
class Student extends Person{
public Student(String name){
super(name);
}
public void doAction(Person other){
System.out.println("This person's name is " + getName());
}
}
Then I implement a main function to test it but I got an error...:
public class TestMain {
public static void main(String[] args) {
Person person;
Student student;
person = new Student("Sam");
student = person;
student.doAction(person);
}
}
It is said student = person receiving an error saying that "Error: Incompatible types: Person cannot be converted to Student". What's wrong with that actually and why...? Does anyone can explain this...?
A Student is a Person, but not every Person is a Student.
If you have a variable of type Person, you can't assign its value to a variable of type Student because, in general, that might not be safe.
If you are certain that it's definitely a Student (e.g. you use an instanceof check, or you have reasoned about the code and thus "know"), you can cast the variable; but one of the central ideas on object-oriented programming is that you shouldn't need to care about the specific subclass.
There are two ways round this:
Assign the new Student() to the Student variable first, and then assign that value to the Person variable:
student = new Student("Sam");
person = student;
student.doAction(person);
This is fine because every Student is a Person, so a Person variable can be assigned the value of a Student variable.
Forgo the student variable entirely, since you only need a reference to a Person on which to call doAction, not specifically a Student:
person = new Student("Sam");
person.doAction(person);
During run-time the person variable can refer to instances of Person which are not instances of Student. Therefore the assignment student = person; is not allowed.
You have to check the run-time type of person and perform a cast in order for the assignment to work (well, the type check is not mandatory, but recommended, in order to avoid potential ClassCastException):
if (person instanceof Student)
student = (Student) person;
package taskassignment;
public abstract class Person
{
public String name;
public Person(String n)
{
name = n;
}
public String getName()
{
return name;
}
public abstract String doAction(Person other);
}
public class Student extends Person
{
public Student(String n)
{
super(n);
}
#Override
public String doAction(Person other)
{
return "The Person Name is : "+ getName();
}
}
public static void main(String args[])
{
Person person = new Student("Sam");
Student student = (Student) person;
System.out.println(student.doAction(person));
}

a little programa to create people

I want to make a program to create people and to show a list of such persons, but do not know if I am doing well and neither logic using "arraylist" to print the results anyone can help me? Thank you very much.
package person;
import java.util.*;
public class Person {
public int Id;
public String Name;
public boolean Show;
public ArrayList people;
public Person(
int identificator,
String thename,
boolean showornot
){
this.Id = identificator;
this.Name = thename;
this.Show = showornot;
}
public void InsertPerson(Person person, ArrayList list){
this.people = list;
list.add(person);
}
}
The main:
package person;
import java.util.*;
public class Trying {
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
Scanner stdin2 = new Scanner(System.in);
Scanner stdin3 = new Scanner(System.in);
Scanner stdin4 = new Scanner(System.in);
ArrayList list_of_people;
list_of_people = new ArrayList();
int option = 0;
int identificador = 0;
String name = "";
boolean show = true;
name = “Toni”;
Person person1 = new Person(identificador, name, true);
person1.InsertPerson (person1, list_of_people);
Iterator ite = list_of_people.iterator();
while(ite.hasNext()){
System.out.println(list_of_people);
}
}
Thanks!
Problem: You are creating the arraylist "people" as a property of each "person" (Saying, each person has a list of people)
Quickfix:
Move public ArrayList people; to your Trying class.
Move public void InsertPerson(Person person, ArrayList list) to your Trying class as well.
Better fix:
I recommend using a PeopleManager class - which contains the arraylist "people" and the InsertPerson method. Then, you use the PeopleManager in Trying to build your people list.
public class PersonManager
{
ArrayList<Person> people;
public PersonManager()
{
people = new ArrayList<Person>();
}
public void InsertPerson(Person person)
{
people.add(person);
}
}
Then, you can remove the arraylist from Person, and the method InsertPerson from Person. You'll need to create a PersonManager in your Trying class.
public ArrayList people; does not belong in the Person class. I would suggest using it your client code (the Trying class) or creating a class People that inherits from ArrayList. You can then add a InsertPerson function to that class if you wish.
I would also suggest using a ArrayList for your collection rather than an ArrayList. See a generic collections tutorial here. You should also create getter/setter moethods instead of using public fields.
So, your classes would be:
public class Person { // ...
public class People extends ArrayList<Person> {
public void InsertPerson(Person person) {
this.add(person);
}
// ...
What everyone else is saying is true, but I think theoretically your code should still work. There is a problem with this line however...
while(ite.hasNext()){
System.out.println(list_of_people);
}
You are outputting the whole list every iteration and probably infinite looping. Change it to something like this...
while(ite.hasNext()){
Person curPerson = (Person)ite.next();
System.out.println(curPerson.Name);
}
A slightly more elegant solution is to ditch the iterator for a foreach loop...
for (Person person : list_of_people) {
System.out.println(person.Name);
}

Categories

Resources