Initialize each element of the array with Student objects - java

public class Student {
int marks;
String name;
char sex;
String email;
}
Student[] s = new Student[10];
public class StudentDemo {
Student s[] = new Student[10];// array Student//
Student s1 = new Student();// Student Object//
s1.setName("John"); //Eclipse says here there is a mistake an ask to delete John//
Student[0]=s1;
}
I have created a Student class with name and other attributes. But now I want to initialize each element of the array with Student objects. Is this code right? Eclipse throws a lot of red dots.
Help.

class Student {
int marks;
String name;
char sex;
String email;
public void setName(String string)
{
// TODO Auto-generated method stub
}
}
public class StudentDemo{
public static void main(String [] args)
{
Student s[] = new Student[10];// array Student//
Student s1 = new Student();// Student Object//
s1.setName("John"); //Eclipse says here there is a mistake an ask to delete John//
s[0]=s1;
}
}
Try this.
Problems in your code:
You wrote your function logic outside of function. Corrected in my
code using main method.
You can't have 2 public classes in a class file. So i made Student file as non-public.
You din't have setter for name property of Student.

Well you never defined a setName method so I am assuming thats why you got the compiler error. Something like this should work inside the Student class
public String setName(String name){
this.name = name;
}

use the reference of the array you created instead of the type of array
Thus, replace Student[0] with s[0]

A lot is wrong with your code.
It should be
Student[] s = new Student[10];
s[0] = new Student();
s[0].setName();
You need to also write your code inside a method. Like so:
public void doStuffHere()
{
// Code goes here.
}
Notice I use that fact that at position 0 there is a Student object and then I just set the name. There is no real reason to use s1.

A few things:
First of all, your first array should be written like this:
Student[] s = new Student[10];
Secondly, you never defined the method setName(String name) in your Student class. This would look something like this:
public void setName(String name)
{
this.name = name;
}
On top of that, you can't just call the method in the class, it needs to go inside a method, constructor, or initialisation block.
For example:
public class StudentDemo
{
Student[] studentArray = initStudentArray();
private Student[] initStudentArray()
{
Student[] ret = new Student[10];
Student s = new Student();
s.setName("John");
ret[0] = s;
...
return ret;
}
}

This can help you.
class Student {
int marks;
String name;
char sex;
String email;
void setName(String name){
this.name = name; //this.name represents the current instance non-static variable
}
public String toString(){ //Overridden Objectclass method for string representation of data
return " Student Name: "+name+
"\n Gender: "+sex+
"\n Email: "+email+
"\n Marks: "+marks;
}
}
public class StudentDemo {
public static void main(String[] args){
Student s[] = new Student[10];
s[0] = new Student();
s[0].setName("John"); //similarly u can set values to other attributes of this object
System.out.println(s[0]); // same as s[0].toString() its an implicit call
}
}

Related

How to add a user-defined data type into a set?

this is my mock test from my professor and I having trouble writing it in Java.
This is the question:
An ADT to manage a collection of students in a course is required. You
can assume that there are no more than 100 students in any course. A
student's record consists of ID (String), name (String), and GPA
(double). There is no duplication in student IDs, but it is possible
to have two or more students with the same name and/or GPA.
Create a new type StudentCollection (it is equivalent to a class in
Java). Except for the constructor, your StudentCollection type must
support the following 3 public operations (feel free to add additional
private operations as needed - but their scope have to be private)
void addStudent(Student std): add a new student std to your
collection. If there is a student having the same ID as std in your
collection already, do nothing.
Student searchByName(String name): search the student collection and
return any student whose name contains name completely (case
sensitive). Examples: "ABC" contains "ABC" completely; "ABC" contains
"A" completely; "ABC" contains "C" completely, "ABC DEF" contains "C
D" completely; "ABC" does NOT contain "CB" completely; "ABC" does NOT
contain "abc" completely. If there is more than one matching student,
your method can return any student. If there is no matching student,
return null. int rankStudent(String sID): return the rank of a student
whose ID is sID with regard to this collection. The ranking is done
using students' GPAs. A student with the highest GPA has a rank of 1.
In this example, let assume there are 4 GPA values [9.0, 8.5, 7.0,
8.5]. A student whose GPA = 9.0 has a rank of 1, a student whose GPA = 8.5 has a rank of 2 (there are 2 students who have the same rank of 2), and a student whose GPA = 7.0 has a rank of 4. If there is no
student found with the provided sID, return -1.
Create a StudentCollection object and use it in the main method
(client code). Your client code must call all the above 3 public
methods one or more times.
You are NOT allowed to use the Java Collection Framework classes for
this problem. Your code for this problem must be stored in a single
file StudentCollection.java.
The ADT I'm choosing here is Set. Since the instruction doesn't allow me to use the Java Collection Framework, I have to manually implement all of the functions.
But here is the problem:
for the first function, the question ask me to write void addStudent(Student std) which when implementing a Set ADT, I cannot pass in a user defined data type Student into the function, I have done some research and we have to pass in a Set parameter instead of a user defined data type. Here is the code for class Student:
static class Student {
private String ID;
private String name;
private double GPA;
Student(String ID, String name, double GPA) {
this.ID = ID;
this.name = name;
this.GPA = GPA;
}
}
let's say that we put in the Student class, then there have to be some getters and setters inside of the Student class. But the question limit the amount of public function to implement and all functions beside the three specify function above have to be private. How can a getter and setter be private? Is it possible?
The overall question is: How to add a user-defined data type into a set?
I'm sorry if there is any explanation of mine is not clear. Please reply to this question if you have any further question.
Here is the code that I have been working on:
import java.util.HashSet;
import java.util.Set;
public class StudentCollection {
static Set<Student> manage = new HashSet<>();
static class Student {
private String ID;
private String name;
private double GPA;
Student(String ID, String name, double GPA) {
this.ID = ID;
this.name = name;
this.GPA = GPA;
}
}
public static void addStudent(Student std) {
manage.add(std);
}
// public static Student searchByName(String name) {
//
// }
//
// public static int rankStudent(String sID) {
//
// }
public static void main(String[] args) {
Student std = new Student("s387", "nam", 3.7);
addStudent(std);
}
}
The Student class has to be public, with public getters. Otherwise, you couldn't create a Student instance to add a student.
I went ahead and coded the addStudent method. I'm leaving the rest of the code for you to finish.
You'll have to go over your class notes to verify, but this is how I would start coding the StudentCollection class. There are no static fields or methods, other than the main method.
public class StudentCollection {
public static void main(String[] args) {
StudentCollection sc = new StudentCollection();
sc.addStudent(sc.new Student("10001", "George", 9.0));
}
private int studentLength;
private Student[] students;
public StudentCollection() {
this.studentLength = 0;
this.students = new Student[100];
}
public void addStudent(Student student) {
for (int index = 0; index < studentLength; index++) {
if (student.getSID().equals(students[index].getSID())) {
return;
}
}
students[studentLength++] = student;
}
public Student searchByName(String name) {
}
public int rankStudent(String sID) {
}
public class Student {
private final double gpa;
private final String sID, name;
public Student(String sID, String name, double gpa) {
this.sID = sID;
this.name = name;
this.gpa = gpa;
}
public double getGpa() {
return gpa;
}
public String getSID() {
return sID;
}
public String getName() {
return name;
}
}
}

How to call a method from a class that contains a constructor?

I recently learned that calling a class that contains a constructor means that it will call the constructor only, but what if I want to call a method from that class in Main?
Let's say I have a class that looks like this
public class Student {
private String lastname, firstname, course;
private int[] grades;
static int total;
public Student(String lastname, String firstname, String course, int[] grades) {
this.lastname = lastname;
this.firstname = firstname;
this.course = course;
this.grades = grades;
}
public boolean hasFailingGrade() {
//statements
}
return failed;
}
public void showDetails() {
//statements
}
}
And in Main, I want to create an instance of Student and call showDetails(), however, the instance references the constructor only. How do I call the method from Student? I searched around but I only found articles regarding how to call a constructor.
Here's how my Main class looks like
import java.util.Scanner;
import java.util.ArrayList;
import java.io.*;
public class MainApp {
public static void main(String args[]) throws FileNotFoundException {
String firstname, lastname, course;
int[] grades = new int[5];
ArrayList<Student> list = new ArrayList<Student>();
Scanner in = new Scanner(new File("person.txt"));
Scanner in2 = new Scanner(new File("person.txt"));
while(in.hasNext()) {
lastname = in.nextLine();
firstname = in.nextLine();
course = in.nextLine();
for (int i = 0; i < 4; i++)
grades[i] = in2.nextInt();
list.add(new Student(lastname, firstname, course, grades));
}
Student studentClass = new Student();
Student.showDetails();
}
}
I think you have a slight misunderstanding of what instantiating an object means. When you make a call to new Student(), you are instantiating a new instance of your Student class. This instantiation process involves an initial call to the constructor. Think of the constructor method as a function that sets up everything you need for your class to work as you expect.
However, once you instantiate and instance of Student, you then have access to all public methods and fields available from that instance. In your example, your Student class has a public method called showDetails().
So you could write something like this in main:
Student student = new Student("Smith", "John", "English", [95, 88, 73]);
student.showDetails();
By creating an instance of the class, you gain access to all public methods on the class.
Hope this clears up your confusion!

How can I add an information to an existing element in an arraylist?

have a question about this code. How can I add information to an existing element? For example in the beginning the machine asks the user to give a name. If I give the name "Harry" the machine will just say "the student name is correct" but I want also to see the age of that student and in general some information. So my question is how can I add informations for each student? Here is my code so far. Thanks in advance!
package test;
import java.util.*;
public class readStudents {
public static void main(String []args) {
ArrayList<String> arrlstStr = new ArrayList<String>(); //Declaring ArrayList
arrlstStr.add("Malte");
arrlstStr.add("Timo");
arrlstStr.add("Harry");
arrlstStr.add("Julian");
arrlstStr.add("Musa");
arrlstStr.add("Mirnes");
arrlstStr.add("Daniel");
arrlstStr.add("David");
arrlstStr.add("Nico");
arrlstStr.add("Ranya");
arrlstStr.add("Xuan");
arrlstStr.add("Sören");
arrlstStr.add("Mark");
arrlstStr.add("Salomon");
arrlstStr.add("Leon");
arrlstStr.add("Niklas");
arrlstStr.add("Tobias");
System.out.println("Enter the name of the student: ");
Scanner scanner = new Scanner(System.in);
String student = scanner.nextLine();
if (arrlstStr.contains(student)) {
System.out.println("This student name is correct");
}
else {
System.out.println("You gave a wrong name");
}
}
}
public class Student {
private String name;
private int age;
// other fields with getter and setter
}
public class StudentFields {
public static void main(String []args){
ArrayList<Student> arrlstStr = new ArrayList<Student>(); //Declaring ArrayList
Student s1 = new Student();
s1.setName("R1");
s1.setAge(20);
arrlstStr.add(s1);
arrlstStr.add(s2);
}
}
A very simple thing to do :)
You will agree with me that, array list is a collection of list of elements. This elements in your case were pre-defined. What I would suggest is that you have to also define the information you want any element to have. For example; student name 'Harry' should have a piece of corresponding information like age pointing to it; student_age; e.g. Harry_age set to '34'. something like this:
arrlstStr.add("Harry");
arrlstStr.add("Harry_age")
assigning value to the element
Harry_age = 34;
The above illustration is to guide you.
Once you have defined that, make you use of your if-statement. The pseudo-code is;
IF student name is "Harry" THEN
DISPLAY 34 (Harry's age)
This should work. Is just simple logic.
As per your requirement I would recommend to use map instead of Array list and keep the student name as key and student object as value so on bases of name you can get student information.such as below
public class Student {
private String name;
private int age;
public Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class StudentData {
public static void main(String []args){
Map<String,Student> studentCollection=new HashMap<String,Student>();
Student student = new Student("Sachin",40);
studentCollection.put(student.getName(),student);
.
.
}
}

Java, Making a class Immutable

I came across this exercise online where I have two classes and I'm supposed to make the Tutor class immutable. However, the only thing I can think of is adding final to name field. When it comes to the constructor, I don't think I need to change the initialisation of the name variable as String is immutable. I'm not sure how to approach the collection and how to make this part of the constructor immutable. According to the exercise, I'm not supposed to change the Student class (which I can see is mutable)
public class Student {
private String name;
private String course;
public Student(String name, String course) {
this.name = name;
this.course = course;
}
public String getName() {
return name;
}
public String getCourse() {
return course;
}
public void setName(String name) {
this.name = name;
}
public void setCourse(String course) {
this.course = course;
}
}
public final class Tutor {
private String name;
private final Set<Student> tutees;
public Tutor(String name, Student[] students) {
this.name = name;
tutees = new HashSet<Student>();
for (int i = 0; i < students.length; i++)
tutees.add(students[i]);
}
public Set<Student> getTutees() {
return Collections.unmodifiableSet(tutees);
}
public String getName() {
return name;
}
}
The Tutor class presents many aspects promoting its immutability :
the class is final
the Set<Student> is protected against the modifications
no method allowing to change directly the state of the class
However, the defensive copy of the constructor is not complete.
It also has to copy the Students elements of the array passed. Otherwise the client of the constructor may change any instance of them and make so the Tutor instance mutable such as :
Student[] students = ...;
Tutor tutor = new Tutor(name, students);
students[0].setName("new Name!"); // break the immutability of Tutor
You should write something like :
public Tutor(String name, Student[] students){
this.name = name;
tutees = new HashSet<Student>();
for (Student student : students){
Student copy = new Student(student.getName(),
student.getCourse());
tutees.add(copy);
}
}
Additionally note that the Set returned by getTutees() is unmodifiable but elements contained in are as Student is mutable.
So to make Tutor immutable you also have to create a copy of the Student elements as you return getTutees() such as :
public Set<Student> getTutees(){
Set<Student> students = new HashSet<>();
for (Student student : tutees){
Student copy = new Student(student.getName(),
student.getCourse());
students.add(copy);
}
return Collections.unmodifiableSet(students);
}
As you may notice, getting the immutability in these conditions (an instance that we wish immutable but that contains a collection referencing mutable instances) requires to write more code (to read/to maintain/to test) and to perform more processing (so slower to execute).
If Student was an immutable class, the original getTutees() and the original constructor would be enough.
Proper way is to make an object immutable is to:
Declare the object final
Do not provide setter methods
Make all fields private
Make mutable fields final
Use deep copy in the constructor
Clone objects in getter methods, so you don't return actual reference.
Do you really need to return the Set of Students? If you really need that you can hide that by using an interface that provides only getters, something like
interface IStudent {
public String getName();
public String getCourse();
}
class Student : implements IStudent { ...}
and in your Tutor you return Set<IStudent>
To make the Tutor class immutable, you should use the "final" modifier on all the fields inside a Tutor, not on the Tutor's class definition.
Java SE 16
You can use JEP 395: Records feature, introduced as part of Java SE 16, to create an immutable class without requiring much ceremony.
If you have already gone through the above link, you must have figured out that you can do it simply as
record Tutor(String name, Set<Student> tutees) { }
What you get in turn are:
A final class Tutor.
A canonical constructor whose signature is the same as the header, Tutor(String name, Set<Student> tutees).
private final fields, name and tutees and their corresponding public accessor method with the same name and return type.
Automatically created equals, hashCode and toString methods.
Demo:
Student.java
record Student(String name, String course) { }
Tutor.java
import java.util.Set;
record Tutor(String name, Set<Student> tutees) { }
Main.java
import java.util.Set;
class Main {
public static void main(String[] args) {
Set<Student> cscStudents = Set.of(
new Student("Harry", "Java-8"),
new Student("Tina", "Java-9"),
new Student("Andy", "Java-11")
);
Set<Student> scienceStudents = Set.of(
new Student("Tony", "Phy"),
new Student("Kerry", "Chem"),
new Student("John", "Bio")
);
Tutor t1 = new Tutor("Mark", cscStudents);
Tutor t2 = new Tutor("Robin", scienceStudents);
Tutor t3 = new Tutor("Mark", Set.of(
new Student("Andy", "Java-11"),
new Student("Harry", "Java-8"),
new Student("Tina", "Java-9")
)
);
System.out.println(t1);
System.out.println();
System.out.println(t1.tutees());
System.out.println();
System.out.println("Students of " + t1.name() + ":");
t1.tutees()
.stream()
.forEach( t -> System.out.println(t.name()) );
System.out.println();
System.out.println(t1.equals(t2));
System.out.println(t1.equals(t3));
}
}
Output:
Tutor[name=Mark, tutees=[Student[name=Andy, course=Java-11], Student[name=Harry, course=Java-8], Student[name=Tina, course=Java-9]]]
[Student[name=Andy, course=Java-11], Student[name=Harry, course=Java-8], Student[name=Tina, course=Java-9]]
Students of Mark:
Andy
Harry
Tina
false
true

Setters, why won't this work?

I've been toying for hours, changing static, private, public etcetera :) But it still won't work. If I change static at one place, I get an error at another place etc.
I have a class called person. I've used NON-static Setters because the Person() constructor is also non-static.
public class Person {
private String name;
private String lastname;
private String nickname;
Person() {
this.name = "";
this.lastname = "";
this.nickname = "";
}
public void setName(String name) {
this.name = name;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
Then I have a file with my main method, and different methods for interacting with the user.This method is also static because it calls that methods that take the userInput which is using the Scanner class.
public class Interaction {
public static void takeName() {
String name;
String lastname;
String nickname;
System.out.println("What is your firstname:");
name = userInput(); // calls method with Scanner class
System.out.println("What is your lastname:");
lastname = userInput(); // calls method with Scanner class
System.out.println("What is your nickname:");
nickname = userInput();
person.setName(name);
person.setLastname(lastname);
person.setNickname(nickname);
}
//editor: missing closing bracket
What I've tried:
I've tried to dat Person.person.setname(name);
Declare the String in the public class Interaction, and then pass the String using this.name and call the method from the public class Interaction
tried to change static, private etc. etc.
Delete the constructor class Person() in Person class.
What am I missing here?
EDIT: I'VE ADDED SOME MORE INFO as you requested :)
My new Person object will be declared if it passes an if statement.
IF there is a place available then a new person will be created and added to this place.
public class Theater {
void reservationSystem () {
if (availability > 0) {
for (int i = 0; i < freespaces.length; i++) {
if (freespaces[i].person == null) {
freespaces[i].person = new Person();
break;
}
}
} else {
System.out.println("No tickets for you today :) ");
}
}
//editor: missing closing bracket
So my way of thinking is:
I fill a constructor with the data from the Userinput() using the Scanner class;
and THEN I create the new Person object so it has that data!
When I create a new Person in the reservation system, then the data in the constructor will be filled with data AGAIN but now with new data :)
If you need any more information please let me know :)
The first thing to note is that your Person constructor is a little useless, you can rewrite Person as such:
public class Person {
private String name = "";
private String lastname = "";
private String nickname = "";
public void setName(String name) {
this.name = name;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
Now onto your Interaction class. This needs to by public rather than Public but I assume that's a typo.
You need to have an instance of Person to call your setters on as they are instance methods. You need to somewhere call new Person().
The easiest way of writing your takeName() method is by creating a Person in the method and returning the instance:
public class Interaction {
public static Person takeName() {
final Person person = new Person();
System.out.println("What is your firstname:");
person.setName(userInput());
System.out.println("What is your lastname:");
person.setLastname(userInput());
System.out.println("What is your nickname:");
person.setNickname(userInput());
return person;
}
}
Your 'takeName()` function should update a single instance of the Person class.
One approach is to create the Person externally and pass it to the function:
Public class Interaction {
public static void takeName(Person person) {
String name;
String lastname;
String nickname;
System.out.println("What is your firstname:");
name = userInput(); // calls method with Scanner class
System.out.println("What is your lastname:");
lastname = userInput(); // calls method with Scanner class
System.out.println("What is your nickname:");
nickname = userInput();
person.setName(name);
person.setLastname(lastname);
person.setNickname(nickname);
}
}
But I think it would be more intuitive to create the person instance inside the function and return it:
Public class Interaction {
public static Person takeName() {
String name;
String lastname;
String nickname;
Person person = new Person();
System.out.println("What is your firstname:");
name = userInput(); // calls method with Scanner class
System.out.println("What is your lastname:");
lastname = userInput(); // calls method with Scanner class
System.out.println("What is your nickname:");
nickname = userInput();
person.setName(name);
person.setLastname(lastname);
person.setNickname(nickname);
return person;
}
}
Because this is not valid syntax: Person.person.setname(name);
What this would mean in this context is:
get class named Person
get static field of Person class named person
find and invoke instance methid setname with argument name
But your Person class - appropriately - does not have a static field named person...
The root cause of your issues is most likely not being entirely familiar with the concept of classes, instances, and in connection, the meaning of static and instance members and methods...
Static always means the referenced part is connected with the class.
Whereas an instance variable or method (e.g. everything non-static) is connected to the instances of said classes.

Categories