Unable to display object array using get(index) - java

I am trying to display the different objects in an ArrayList. In my project context, one student is one object.
I used an ArrayList to store all the different student objects and I am having problems reading the ArrayList.
<%
String student_name = request.getParameter("studentName");
ArrayList<Object[]> studentList = new ArrayList<Object[]>();
if(student_name != null && student_name.length() > 0) {
PreparedStatement preparedStatement = con.prepareStatement("Select * from users where firstname LIKE ? ");
preparedStatement.setString(1, "%" +student_name+ "%");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
String first_name = resultSet.getString("firstname");
String last_name = resultSet.getString("lastname");
String email = resultSet.getString("email");
Object[] student = {first_name,last_name,email};
studentList.add(student);
session.setAttribute("studentObject",studentList);
//System.out.println("First Name: " + first_name + "," + "Last Name: " + last_name);
System.out.println(studentList.get(0));
}
When I try to display (studentList.get(0)), all I see is "[Ljava.lang.String;#XXXX"
How do i get it to display the different student objects based on the index ?

At first, It will be more idiomatic in Java to define your own class Student. Write an extractor to that class, define toString method and it will be great.
Java requires you to define toString method to any type of object that will be printed. So, you have to define toString for your Student class.
But you are using an array. Java doesn't have toString method defined for Arrays. So I would propose you to do something like this. (I'm a bit on rush so code may contain some mistakes:
// At first it could be better to define a structure
// that represents a student
// class must be defined in separate file like Student.java
// Student.java
public class Student {
// constructor for the Student object
public Student(final String firstName,
final String lastName,
final String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
private String firstName;
private String lastName;
private String email;
#override String toString() {
return firstName + " " + lastName + " " + email;
}
// getters
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public String getEmail() { return email; }
// setters
public void setFirstName(final String firstName) {
this.firstName = firstName;
}
public void setLastName(final String lastName) {
this.lastName = lastName;
}
public void setEmail(final String email) {
this.email = email;
}
} // end of Student.java file
///////////////////////////////////////////
final ArrayList<Student> studentList = new ArrayList<Student>();
.... // your code
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
// creating a new student with new keyword
final Student currentStudent = new Student(
resultSet.getString("firstname"),
resultSet.getString("lastname"),
resultSet.getString("email")
)
// you are adding a student object to the list
studentList.add(currentStudent);
session.setAttribute("studentObject",studentList);
// that should work
// toString method will be called implicitly
System.out.println(studentList.get(0));
}
// So you will have a list of students
// that will be accessable in the following manner:
studentList.get(0).getFirstName;
studentList.get(1).setFirstName("New name");
If you want a different behaviour you may call those fields directly, or modify
the behavior of toString method
Java also assumes that you're using camelCase notation, you may find in in the style guide.
Hope it helps.

Try java.util.Arrays class:
System.out.println(Arrays.toString(studentList.get(0)));

Currently you are printing out the Object[] which is not exactly human readable. I would suggest creating a new class called Student. Then have three member variables firstName, lastName, and email. Also create a toString() method for this new class. Then you can have an ArrayList of Students. This should simplify everything for you.

You have at least two options:
Implement an object corresponding to Object[] student:
In this class you may override Object's toString(), and implement it as to wish to present the data.
NOTE: this is very relevant to you because when printing studentList.get(0) you actually print call Object's default toString() which returns the reference to the object.
For more information regarding default Object.toString() here.
The simplestway is to use Arrays.toString():
System.out.println(Arrays.toString(studentList.get(0)));

It looks like you're not trying to display a String as you expect, you're trying to display an array of Objects.
You could try : System.out.println(studentList.get(0)[0]);
You'll have an idea

Related

How in JPA mappe into one column values of two other columns?

I am using JPA, and in my DB I have a table student with columns: id, firstname and firstAndLastname
So I did an Entity to mappe data, I can get lastname from another table, but I don't persist it as there is no columns lastname in DB.
How to store in column firstAndLastname that is concatenation of firstname and lastname and store it in specific column, example : firstname : John, lastname : Doe => firstAndLastname : JohnDoe
#Entity
#Table(name = "student")
public class Student implements Serializable {
#Id
#Column(name = "id")
private Integer id;
#Column(name = "firstname")
private String firstname;
#Transient
private String lastname;
#Column(name = "firstAndLastname")
private String firstLastname;
I tried this (and not working) :
public String getFirstLastname() {
return this.firstname+ this.lastname;
}
Any idea ?
Genetate getters/setter for all properties of the Entity.
Instantiate the object to save: Student student = new Student(1,"Mario","Rossi");
Call the setter : student.setFirstLastName(student.getFirstName()+student.getLastName());
myStudentService.save(student);.
If you still haven't figured out how to persist data to the database, that's where you need to start. You don't persist data in the JPA itself, that's just the structure for the object. You will build an instance of the Student object in another Class, set the values, and persist it to the database.
You would set that firstLastName value where/when you are creating an instance of your Student.
This is just a rough explanation. Not explicit code for you.
You would have a class like:
public class SaveStudentService {
public saveStudent(){
Student student = new Student();
student.setFirstName("test");
student.setLastName("lastTest");
student.setFirstLast(student.getFirstName + " "+ student.getLastName);
studentRepo.save(student);
}
}
You'll have your normal getters and setters in your Student class...
public Student getfirstName() {return this.firstName;}
public Student setfirstName(String firstName) {return this.firstName = firstName;}
public Student getfirstLast() {return this.firstLastName;}
public Student setfirstName(String firstLastName) {return this.firstLastName = firstLastName;}
I would recommend 2 approaches:
If you instantiate object by constructor:
public Student(final Integer id, final String firstname, final String lastname) {
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
this.firstLastname = String.join(firstname, lastname);
}
By setter:
public void setFirstLastname(final String firstName, final String lastName) {
this.firstLastname = String.join(firstName, lastName);
}
In addition you can also use Spring AOP and advice save method on your repository but it's less readable and more difficult to maintenance.
#Before("execution(* com.package.StudentRepository.save(..))")
public void updateFirstLastName(final JoinPoint joinPoint) {
final Object[] arguments = joinPoint.getArgs();
// find Student.class object and update firstLastName field
}
Either way - don't perform concatenation outside Student class because it leads to boilerplate and it's harder to maintenance.
But IMHO the best approach is to store firstName and lastName separately in database and use SQL CONCAT function if needed.

trying to call superclass method in subclass

Probably a pretty noob question, but I cant figure it out. I have a class Person to store a name that is input from the keyboard
public class Person {
private String firstName;
private String lastName;
public Person()
{
firstName = "";
lastName = "";
}
public Person(String first, String last)
{
setName(first, last);
}
public String toString()
{
return(firstName + " " + lastName);
}
public void setName(String first, String last)
{
firstName = first;
lastName = last;
}
public String getFirstName()
{
return firstName;
}
public String getLastName()
{
return lastName;
}
}
I am trying to call the toString method in a subclass called Patient
public class Patient extends Person {
private int patientID, patientAge;
public Patient()
{
patientID = 0; //for a different part of the class that works
patientAge = 0;
}
#Override
public String toString()
{
return ("Patient Name: "+super.toString());
}
}
I cannot get it to output the name in main when I call the toString method from the Patient class, but when I tested it, it output the name when I call the toString method from the Person class.
The method call in main looks like Patient pnt = new Patient(); System.out.print(Pnt.toString());
it prints out in the console "Patient Name: ". Any feedback on what I am doing wrong or ideas on how to get it to work
Here:
public Person()
{
firstName = "";
lastName = "";
}
Your subclass is missing a reasonable call to a super class constructor. So when you instantiate your Patient objects, the above constructor is used, and all patients end up with "" as first and last name!
When you create a Patient, then a patient should have a name, too! But your constructor in Patient only sets the Patient related fields. And implicitly, the default super constructor is called. Therefore the Person fields are all set to be empty strings!
A much better approach would look like this:
class Person {
private final String firstName;
... lastName
public Person(String firstName, String lastName) {
this.firstName = firstName;
...
and then
class Patient extends Person {
private final int patientID;
public Patient(int patientID, String firstName, String lastName) {
super(firstName, lastName);
this.patientID = patientID;
)
Why is that better: names and IDs don't change (normally). There is no point in having getters for them. You create your object once, and then that data is fixed! There is also no point in having that default constructor in Person. A person with empty names doesn't make sense. Thus: don't create a class that allows you to create "invalid" objects. Your classes model reality. There are no real people without names!
And one other hint: use #Override when overriding methods, so that the compiler can tell you when you get something wrong!
if the problem is to output the name in main when you call the toString method from the Patient class, I think the code bellow will help you.
have you tried to construct the Patient object like this?
public static void main(String[] args) {
Patient p = new Patient();
System.out.println(p.toString());
}
Actually I do not see problem in your code.
Person person = new Person();
person.setName("aa", "bb");
System.out.println(person); // aa bb
Patient patient = new Patient();
patient.setName("cc", "dd");
System.out.println(patient); // Patient Name: cc dd
I think that you set name wrong pr use not correct reference. Check it.
You don't have any constructor for your PATIENT subclass. You don't set any firstName or lastName to any patient.
To keep familiar constructor as you used in your parent class, tru to use:
public Patient() {
super("default_firstName", "default_lastName");
this.patientID = 0;
this.patientAge = 0;
}
public Patient(String firstName, String lastName, int patientAge) {
super(firstName, lastName);
this.patientID = 0; //can be implemented some method for automatically setting numbers
this.patientAge = patientAge;
}
This way you always get firstName and lastName even if constructor will be called empty.
According to you toString method, it's correct and it call super class method:
#Override
public String toString()
{
return("Patient name is "+super.toString());
}
But notice that you return STRING value so to make it visible on the screen remember to use:
System.out.println(patient.toString());
Then it will be visible :)
I have added some comments and code in your Person class that should fix your issues.
public class Person {
private String firstName; //store the first name
private String lastName; //sore the last name
//initialize firstName and lastName to an empty string
public Person() {
firstName = "";
lastName = "";
}
//set firstname and lastname according to the parameters.
public Person(String first, String last) {
//setName(first, last); remove this crap.
// Use the contructor properly when initialize your person object. Like this:
this.firstName = first;
this.lastName = last;
}
//method to output the first name and last name
#Override
public String toString() {
return (firstName + " " + lastName);
}
//method to set firstName and lastName according to the paramters
public void setName(String first, String last) {
//
firstName = first;
lastName = last;
}
}

i Have written this membership class, how can i create a method to find a specific ID given to a member?

Guys this is my membership class so far, i am struggling to create a method that finds the full members details that i have given just using a uniqueId finder. Please help.
public class Membership {
private String FirstName;
private String LastName;
private int memberId;
private String listOfMembers;
private int uniqueId;
private long phoneNumber;
public Membership(String FirstName, String LastName, int uniqueId,
long phoneNumber)
{
this.uniqueId = uniqueId;
this.FirstName = FirstName;
this.LastName = LastName;
this.phoneNumber = phoneNumber;
}
public String getMember()
{
return FirstName + LastName;
}
public String getlistOfMembers()
{
return (FirstName + LastName);
}
public int getId()
{
return uniqueId;
}
public void MemberId (int Id)
{
System.out.println("Id" + Id);
}
public String getMemberDetails ()
{
System.out.println("Member Id: " + uniqueId);
System.out.println("first name: " + FirstName);
System.out.println("LastName: " + LastName);
System.out.println("Member phone number: " + phoneNumber);
return listOfMembers;
}
}
This is what i have done so far.
Issues:
You've got user interface code where it doesn't belong. I would remove all System.out.println statements from this class and instead leave it in a UI class or main method (if very simple).
In particular, getter methods should return field values, and should not have System.out.println statements
I'm not sure why this class has a listOfMembers field, or why it's just a String. You look to be trying to combine Member and Membership together in one single class -- Don't do this.
I'd name this class Member since it holds information for just a single Member.
If I needed a Membership class, it would instead hold an ArrayList<Member>
And it would have a public Member getMember(int id) method that would return the item in the list above that shares the id passed into the method. A simple for loop that iterated through the list, comparing id's would suffice.
To add on Hovercraft's answer with an example.
You have your class handling all the members, very basic implementation of it.
public class Membership {
private final Map<Integer, Member> members = new HashMap<>();
public void addMember (Integer uniqueId, Member member) {
members.put (uniqueId, member);
}
public void getMember (Integer uniqueId) {
return members.get (uniqueId);
}
...
}
Then you have the Members themselves like this, more fields can be added as you want them.
public class Member {
private String firstName;
private String lastName;
public Member (String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName () {
return firstName;
}
...
}
This is a very basic, but strong, feature in OOP to use.
Again see Hovercraft's answer as it provides all the details. If they were to edit/remove I will update this one.
Map vs List
One minor thing is I'd vote against using an ArrayList<E> to store the Members. If you add to the implementation that you can remove users the uniqueId will shift from user to user. Instead I would be for making sure that you are not adding to an existing user.
If you want to keep it simple and just get going, an ArrayList<E> works, do know the problem you might get in the feature, an uniqueId is not necessarily tied to a Member.
"I am quite new to java and have never come across "map" can you please explain what it is?"
"An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value." - From: Documentation.
Instead of working with direct indexes as you do in an Array:
arr[5]; // here you get the value at index position 5.
Or like a List:
list.get(5); // here you get the fifth element, it can be stored (almost) anywhere in the memory, before or after 4, doesn't matter, as 4 knows where 5 is.
And for a Map:
map.get(5); // you get the object stored at 5, there might not be a 3 or 4 in the Map. You can store any Objects as anything. A String is another example of a common key.
I would suggest to use Map and use id as key of Map and store object of Membership as Value,thereby easy to retrieve and store also.
Something similar to this,
Map<Integer,Membership> map = new HashMap<Integer,Membership>();
Membership m = new Membership("First", "LastName", 1,1234567890);
map.put(m.getId(), m);
To get member by id,
System.out.println(map.get(id).getMemberDetails());

Ignore default constructor and use constructor with parameters in Java

I am not very well rounded in Java, which is why I am asking this question that is probably very stupid sounding. Nonetheless, I am trying to figure out how to ignore a class's default construct method, and use a construct method with parameters instead. For example, something like this:
public class Name {
String firstName, lastName;
public Name()
{
String dialog = JOptionPane.showInputDialog("First and Last name: ");
Scanner inName = new Scanner(dialog);
firstName = inName.next();
lastName = inName.nextLine();
}
public Name(String newFirst, String newLast)
{
firstName = newFirst;
lastName = newLast;
}
}
I then have a class called Student which extends name as such:
public class Student extends Name
{
public Student(String firstName, String lastName)
{
firstName = firstName;
lastName = lastName;
}
}
So, the first construct method from Name class prompts the user to enter their name, but say I already know the user's name and have it stored in some variables, how can I create a new Student() object (which is really a name() object) without invoking that first default constructor, and instead invoke it as such:
Student student1 = new Student(firstName, lastName);
I understand why the following line would call the default construct method:
Student student1 = new Student();
But the next following line stil calls the same parameterless construct method, even though I am using parameters:
Student student1 = new Student(firstName, lastName);
What am I doing wrong here?
First : using a Scanner to get an input from the external world in a constructor is a terrible idea.
Second : the constructor in Student calls the constructor in Name that takes no parameters since there is no explicit call to super(). If you want to avoid that :
public Student(String firstName, String lastName)
{
super(firstName, lastName);
}
If you don't explicitly call a super constructor from the subclass, it implicitly calls the super constructor that takes no arguments.
To make it more clear, when you write
public Student(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
you are in fact doing :
public Student(String firstName, String lastName)
{
super();
this.firstName = firstName;
this.lastName = lastName;
}

Java, I need help instantiating an object

Hello I'm new to Java. I'm trying to create a object and pass name through it. I don't have a clue what I'm doing wrong?.
public class Employee
{
private String name, number;
private String date;
public Employee()
{
name= "";
number = "";
date = "";
}
public Employee(String name, String number, String date)
{
setName(name);
setNumber(number);
setDate(date);
}
public void setName(String n)
{
name = n;
}
public void setNumber(String n)
{
number = n;
// you can check the format here for correctness
}
public void setDate(String d)
{
date = d;
}
public String getName()
{
return name;
}
public String getNumber()
{
return number;
}
public String getDate()
{
return date;
}
}
import java.util.Scanner;
public class TeamLeadDemo
{
public static void main(String[] args)
{
String name;
// create scanner object
Scanner keyboard = new Scanner(System.in);
// inputting data
System.out.println("Enter Name:");
name = keyboard.nextLine();
// instantiating object, HERE IS THE PROBLEM
Employee thename = new Employee(name);
// outputting data
System.out.println("Employee Name:"+thename.getName());
System.out.println("Employee Details:\n" + thename);
}
}// Function definition
What should i do??
Hey fellow newbie programmer!
Take a look at how you initialize your object:
Employee thename = new Employee(name);
Since you only give it the String name as a parameter, Java cannot initialize your Employee object because it does not have a single argument constructor!
Here are your constructors method signatures:
public Employee()
public Employee(String name, String number, String date)
One takes no arguments, and the other takes 3 arguments.
If you look at the way you initialize it, you only pass 1 argument!
You would need to create a new Constructor that has a single argument in order for your code to work. Or easier yet, you could just pass in "", "" for your number and date string values.
More experienced programmers please do not hesitate to correct my programming semantics if they are wrong. I feel like I'm using words that I do not fully understand.
You need a constructor that receives only the name that you are passing:
public Employee(String name) {
this.name = name;
this.number = "";
this.date = "";
}
Currently you only have one default constructor and one that receives all three properties.
Your Employee class has two constructors: one taking zero arguments and one taking three arguments. Yet you're attempting to construct it with one argument. That wouldn't compile.
There are two possible solutions:
Add another constructor taking one argument.
public Employee(String name) {
this.name = name;
}
Use the constructor taking three arguments and pass null through.
Employee employee = new Employee(name, null, null);
Unrelated to the concrete problem, setting values to empty strings in the default constructor and calling the setters in the second constructors is not a nice practice. In the first, just do nothing, keep them default null. In the second constructor, you should prefer setting the property directly instead of calling the setter.
You need to pass in the number and date to the constructor as well. Try:
Employee thename = new Employee(name, "", "");
Employee thename = new Employee(name);
You have no constructor that takes only one String
If you have some very very strong reasons not to use Employee thename = new Employee(name, "", "");, you may try "varargs"
As :
public class Employee {
String fname="";
String lname="";
public Emp(String... attrs) {
if ( attrs.length > 1 ) {
fname = attrs[0];
lname = attrs[1];
}else if(attrs.length == 1) {
fname = attrs[0];
}
}
public String toString() {
return fname + " " + lname;
}
public static void main(String[] args){
Employee e1 = new Employee ("Test");
Employee e2 = new Employee ("Test" ,"case");
System.out.println(e1);
System.out.println(e2);
}
}
Caution : this is just to answer your question- Think before using in real world situations. Not from design/ best approach perspective. But it is different and caters to your question though ;-)

Categories