I have a problem retrieving a Student's info from a list, or deleting it... Heelp... Code below:
import java.util.*;
public class Directory
{
private TreeMap<String, Student> studentList;
private int numberOfEntries;
public Directory()
{
studentList = new TreeMap<String, Student>();
numberOfEntries = 0;
}
public void addStudent(Student newStudent)
{
studentList.put(newStudent.StudentInfo(), newStudent);
//numberOfEntries++;
}
public void StudentInfo(String StudentInfo)
{
Object obj = studentList.get(StudentInfo);
System.out.println(obj);
}
public void removeStudent(String StudentInfo)
{
Object obj = studentList.remove(StudentInfo);
System.out.println(obj + "Removed");
}
public void printStudentList()
{
System.out.println("List of Students: " + studentList.keySet());
}
}
======= Student class ======== (Persons contains first, last & email)
public class Student extends Persons
{
private String Sclass;
public Student(String Lname, String Fname, String Email, String Sclass)
{
super(Lname, Fname, Email);
this.Sclass = Sclass;
}
public String StudentInfo()
{
return " Full Name " + Lastname + " " + Firstname + "\n" +
"E-Mail: " + Email + "\n" +
"Class Attending: " + Sclass;
}
public String getName()
{
return Lastname;
}
}
I could try and debug this for you, but that would defeat the purpose. (This is your homework ... and the purpose is for you to learn how to do this yourself.)
My advice is as follows:
FIRST fix the style errors:
The names of variables should always start with a lower-case letter ... unless they are static final constants.
The names of methods should always start with a lower-case letter
Method and variable names should also be meaningful and consistent. For instance:
public void removeStudent(String StudentInfo)
Here StudentInfo actually needs to a student name, not a "student info" string as created by the StrudentInfo method ...
Another example: lname and fname are not meaningful. (I can guess what they mean, but that is not good enough.)
Create yourself a tester program that created instances of those classes and performs a sequence of tests on them. Start with simple things, then move on the more complicated ones.
(In the real world, we'd set up a more formal set of "unit tests" ... but you are probably not ready for that yet.
In fact, if you choose more meaningful names, and then look carefully at how those names are used, your error should "leap out and hit you on the nose".
But you will get maximum benefit if you go through the process yourself.
Related
My code writes the name to the XML document but it does not write any of the test scores. The test scores always output 0 even when I change the name. I would greatly appreciate any help in figuring out why that is the case. I have attached the class with the main method and the class with the constructor. Thank you for the help!
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Studentp194Runner {
public static void main(String[] args)
{
Studentp194 s1 = new Studentp194();
Scanner reader = new Scanner(System.in);
System.out.print("Enter student name: ");
s1.setName(reader.nextLine());
System.out.print("Enter the student's first score: ");
s1.setScore(1, reader.nextInt());
System.out.print("Enter the student's second score: ");
s1.setScore(2, reader.nextInt());
System.out.print("Enter the student's third score: ");
s1.setScore(3, reader.nextInt());
try
{
FileOutputStream fos = new FileOutputStream(new File("./student.xml"));
XMLEncoder encoder = new XMLEncoder(fos);
encoder.writeObject(s1);
encoder.close();
fos.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
try
{
FileInputStream fis = new FileInputStream(new File("./student.xml"));
XMLDecoder decoder = new XMLDecoder(fis);
Studentp194 p2 = (Studentp194)decoder.readObject();
decoder.close();
fis.close();
System.out.println("Student 1 name: " + p2.getName());
System.out.println("Test 1: " + p2.getScore(1));
System.out.println("Test 2: " + p2.getScore(2));
System.out.println("Test 3: " + p2.getScore(3));
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
public class Studentp194 {
//instance variable
private String name;
private int test1;
private int test2;
private int test3;
//constructor method
public Studentp194()
{
}
public Studentp194(String name, int test1, int test2, int test3)
{
this.name = name;
this.test1 = test1;
this.test2 = test2;
this.test3 = test3;
}
//Other Methods
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setScore(int i, int score){
if (i == 1)
test1 = score;
if(i == 2)
test2 = score;
else
test3 = score;
}
public int getScore(int i)
{
if (i == 1)
return test1;
if (i == 2)
return test2;
else
return test3;
}
public int getAverage()
{
int average = (int)Math.round((test1 + test2 + test3) / 3);
return average;
}
public int getHighScore()
{
int highScore = test1;
if(test2 > highScore)
highScore = test2;
if(test3 > highScore)
highScore = test3;
return highScore;
}
public String toString()
{
String str = "Name: " + name + "\n" +
"Test 1: " + test1 + "\n" +
"Test 2: " + test2 + "\n" +
"Test 3: " + test3 + "\n" +
"Average: " + getAverage();
return str;
}
}
The shortest possible answer that is technically correct but useless to someone not familiar with Java beans: Studentp194 does not have a score property. Therefore the non-existent score property is not encoded to XML by XMLEncoder.
To really understand what's going on, if you want to continue to use XMLEncoder, which may or may not be the best solution for the real problem you are trying to solve, you have to read up on the staggeringly ancient but (IMHO) terrific Java Beans specification.
For any arbitrary class to have a Java Beans property named, say, foo, whose type is Foo, then it has to have a public Foo getFoo() method and a public void setFoo(Foo foo) method. As you can see, your Studentp194 class does not have a public int getScore() method, nor does it have a public void setScore(int score) method.
(Of course, the Java Beans specification does not actually mandate that these are the required names of your methods. You can customize them in a number of ways, including the usage of BeanInfo classes, but that is well beyond the scope of this question.)
Getting back to your question and your code, XMLEncoder won't help you here with your class design as-is since your getScore method takes parameters, and your setScore method takes more than one parameter. Therefore they are not Java Beans properties; therefore XMLEncoder is not going to, well, encode them.
Let's say you wanted for whatever reason to continue using XMLEncoder. Then you'd have to refactor your class to conform to the Java Beans specification. I'll leave that as an exercise for the reader. :-)
I'm guessing this is some kind of assignment, and that using XMLEncoder is a requirement of the assignment. If I'm wrong, then look at a different file format for storing your information and retrieving it.
If I'm right, then you want to look at the fact that your Studentp194 class is logically associated with a collection or array of scores. You may want to look in the direction of actually creating a class to represent a test score, and storing a collection of such test scores in your Studentp194 class. Even better yet, perhaps your Studentp194 class wants to be related to another class like Transcript or something similar where this information could be stored properly. For more on this decompositional approach to breaking down problems, read up on "third normal form" and go from there. I hope this helps and welcome to StackOverflow.
I am "learning Java" using a tutorial. One of the lessons involves constructors calling constructors.
After the lesson I did some playing around doing "strange stuff" and I can't figure out what is happening.
I attached an image file captured from the Eclipse screen. (don't be hating).
I thought that would be better because it shows the output screen.
I would expect "name" to be "Arnie" the first time it is printed in the second constructor.
Why is it "Bertie"?
class Machine {
private String name;
private int code;
public Machine() {
this("Arnie", 0);
System.out.println("First constructor running: " + name);
}
public Machine(String name) {
this("Arnie", 0);
System.out.println("Second constructor running before 'this.name': " + name);
this.name = name;
System.out.println("Second constructor running after 'this.name': " + name);
}
public Machine(String name, int code) {
this.name = name;
this.code = code;
System.out.println("Third constructor running: " + name + " " + code);
}
}
public class Application {
public static void main(String[] args) {
Machine machine1 = new Machine();
Machine machine2 = new Machine("Bertie");
Machine machine3 = new Machine("Chalkie", 7);
}
}
It is printing the name variable that is passed in to the constructor. Leaving everything the same, you would see "Artie" if you were to change name to this.name.
The reason is that the constructor that takes the name argument is shadowing the property String name. Either change constructor argument to something other than name, or change lines 12 and 14 to be this.name.
import java.util.ArrayList;
import java.util.Scanner;
public class JavaApplication10Arraylistandobjects {
static Scanner user_input = new Scanner(System.in);
public static void main(String[] args) {
test();
}
public static void test(){
ArrayList<mainclass> me = new ArrayList <> ();
mainclass ob;
for (int i=0;i<2;i++){
ob = new mainclass();
System.out.println("name");
ob.name = user_input.nextLine();
System.out.println("sname");
ob.sname = user_input.nextLine();
me.add(ob);
}
System.out.println("Show List: " + me);
System.out.println("Confirm if is true or false: " + me.get(1).toString().contains("max"));
System.out.println("what is index of: " + me.get(1).toString().indexOf("max"));
}
}
public class mainclass {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
#Override
public String toString() {
return "mainclass{" + "name=" + name + ", sname=" + sname + '}';
}
String name;
String sname;
}
My questions is how can I find correctly indexOf string.
For example when I am checking if string "max" exist - it shows me "true"
and when I am trying to find index of string "max" it shows me index 15 which is not correct.
P.S. I found an article with the same problem where it says that I have to override equals and hashcode - I've done it but anyway I got the same problem.
Please point me to the right direction.
What I am doing wrong here, can someone explain me pls.
These are my inputs and output.
run:
name Jony
sname Bravo
name max
sname hitman
Show List:[mainclass{name=Jony, sname=Bravo}, mainclass{name=max, sname=hitman}]
Confirm if is true or false: true
what is index of: 15
BUILD SUCCESSFUL (total time: 11 seconds)
The line:
System.out.println("what is index of: " + me.get(1).toString().indexOf("max"));
has a problem, in that you're getting the object in the me list at index 1, getting its toString(), and looking for "max" in there. What you actually want to do, as I understand it, is look through the me list and find the place in the list with "max" in it.
P.S. I found an article with the same problem where it says that I have to override equals and hashcode - I've done it but anyway I got the same problem.
If you did that, it would allow you to do something like this:
x = new mainclass();
x.setName("Max");
System.out.println("what is index of: " + me.indexOf(x));
However, there's still a potential problem. Unless you set your equals() and hashCode() to only look at the name and not also sname, then it's not going to find anything unless the sname also matches.
I want to create a program to save country code and search the country code. Also, there are at most 20 counters for saving country code. I am a new java beginner. I want to know what is the correct way to write the searchCoutryCode
method by using arrays to search the saved country code before?
public static void createCountryCode(String countryName, String countrycode) {
if (nameCounter >= 20) {
System.out.println("Full");
} else {
System.out.println("Saving the number of " + countryName + ":" + countryCode);
}
countryNameRec[countryNameCounter++] = countryName;
countryCounterRec[countryCounter++]= countryCode;
}
public static void searchCoutryCode(String countryName) {
for(int i = 0; i <=20; i++){
if(countryNameRec[i].equals(countryName)){
System.out.println("countryNameRec[i]+ " : "+ coutryCodeRec[i]");
} else {
System.out.println("No records");
}
}
}
This code assumes country names are unique. In your code you were giving a message about, list size full but adding records anyway. For this kind of problems as recomended by others using maps more suitable.
public static HashMap<String,String> countries = new HashMap<>();
public static void createCountryCode(String countryName, String countrycode) {
if (countries.size() >= 20) {
System.out.println("Full");
} else {
System.out.println("Saving the number of " + countryName + ":" + countrycode);
countries.put(countryName,countrycode);
}
}
public static void searchCoutryCode(String countryName) {
String countryCode = countries.get(countryName);
if(countryCode == null){
System.out.println("No records");
}
else{
System.out.println("countryName+ " : "+ countryCode");
}
}
Iterating in an array to find an element is not an efficient way.
Well, as you have only 20 elements, it will very probably not cause a real issue but whatever you could have more elements to handle later and this way of doing is besides verbose.
Using a binarySearch (Arrays.binarySearch()) with a sorted array or using a Map would be probably better.
Note that actually your searchCoutryCode() doesn't return nothing.
A search method have to return something : the element that it founds or nothing.
You could return String :
public static String searchCoutryCode(String countryName) {
...
}
or better Optional<String> to handle in a cleaner way the not found case :
public static Optional<String> searchCoutryCode(String countryName) {
...
}
I would recommend learning about Maps. They're a smarter version of arrays, and act like dictionaries with "keys" being like the words and "values" being like a definition. Your entire method can be replaced using a call to the containsValue() or containsKey() method from the java library.
However, if you want to use arrays, i would recommend looking into the binary search methods which are part of the Java Arrays library.
I have a test file and according to it I need to build my program the test file
is below. However, I confused by s1.showDetails(System.out); I have never met
System.out in parameter can anyone help. What to do with it??? when I am trying to write showDetails() the compiler writes mistake. my student code is beneath this Thank you in advance!
import java.util.*;
public class Q2 {
public static void main(String [] args)
{
// Start on section A
System.out.println("Question 2");
System.out.println("Start on part A");
Student s1 = new Student("John", "Smith", 42);
s1.showDetails(System.out);
Course cs = new Course("Computer science");
}
}
public class Student {
private String name;
private String familyName;
private int moduleMark;
private int total;
protected Student(String name, String familyName, int moduleMark)
{
this.name = name;
this.familyName = familyName;
this.moduleMark = moduleMark;
}
public String getName()
{
return name;
}
public String getFamilyName()
{
return familyName;
}
public int getModuleMark()
{
return moduleMark;
}
public String showDetails()
{
return (this.name + " " + this.familyName + " " + moduleMark + total);
//print(name);
}
}
System.out is a variable like every other variable.
System is a class
out is a public static variable inside System of type PrintStream. So you can access it with System.out
So System.out.println(..) is just a call to the println(..) function of a PrintStream
So your function should look like:
public String showDetails(PrintStream stream) {
...
}
The error pretty much describes what the problem is.
The method showDetails() in the type Student is not applicable for the arguments (PrintStream) at Q2.main(Q2.java:9)
The program tries to call your method with System.out which happens to be a PrintStream. So, change your showDetails to
public String showDetails(PrintStream out) {
out.println(this.name + " " + this.familyName + " " + moduleMark + total);
}
This allows the tester (I assume there is a program which tests your assignment for correctness) to give you any PrintStream, either System.out or any other PrintStream.
The error essentially means that the compiler didn't find the method with the name showDetails that takes an argument of type PrintStream. You have no need to pass the System.out to the showDetails() method. The correct way writing the showDetails() is below. Read about System.out.
public void showDetails()
{
System.out.println(this.name + " " + this.familyName + " " + moduleMark + total);
}
Your program can't compile.
Your main is using a method named showDetails that takes a PrintStream as a parameter (System.out). And you are defining only a method named showDetails without parameter.
Look at the doc of System.out. It s a field like any other of the class System. Indeed it's somewhat special as it is static but that doesn't change the game that much...
So write a method with the correct parameter list and you will get closer.
public String showDetails(PrintStream stream) {
//your code here
}
showDetails should write to the stream passed in parameter.
While you are at learning programming. Try to separate query from command. It's a good principle : a method should do one thing : either do something to your current object using a parameter or answer a query about the state of your current object. Not both.
Here you return a string and require a stream... You should better split that into 2 methods : one to get the string and then as second one to call stream.write on that string.
public String toString() {
//your code here
}
public void showDetails(PrintStream stream) {
//your code here
}
Since the print is commented out from your showDetails message there are 2 obvious solutions
The showDetails message is not meant to print out anything (despite the name) and you should just print it out in the main method
System.out.println( s1.showDetails() );
The showDetails message should print the String to any PrintStream, and then you have to adjust both the signature of that method as well as the implementation
public String showDetails(PrintStream stream) {
stream.println( ... );
}