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.
Related
I'm a newbie to Java and I attempt to achieve Polymorphism with the requirements of using the following:
super keyword
overriding
having more than two classes
getting the user's input
using do-while
creating objects
It doesn't have any errors but I doubt if it still makes any sense.
Does it follow Polymorphism still? If not, How can I improve it?
Here is my code:
public class Sample Code {
public static void main(String[] args) {
//declare variables
String name, fSong;
int aNum;
fSong = " ";
Zayn a1 = new Zayn();
a1.makeMusic();
Songs a2 = new Songs();
a2.setName("Zayn");
a2.displayName();
a2.makeMusic();
Lyrics a3 = new Lyrics();
a2.displayName();
a3.makeMusic();
//get values
Scanner in = new Scanner (System.in);
do{
System.out.print("Enter Your Name (2-20 characters): ");
name = in.nextLine();
}while(name.length() < 2 || name.length() > 20);
System.out.print("\nCHOOSE YOUR FAVORITE SONG :\n\n");
System.out.print("[1] Pillowtalk \n");
System.out.print("[2] Dusk Till Dawn\n");
do{
System.out.print("\nEnter Your Choice (1-2): ");
aNum = in.nextInt();
}while(aNum < 1 || aNum > 2);
//determine aNum
if(aNum == 1) {
fSong = "Pillowtalk";
}else if(aNum == 2){
fSong = "Dusk Till Dawn";
}
//Display output
System.out.print("\n[OUTPUT]\n\n");
System.out.printf("Your Name: %s\n", name);
System.out.printf("Your Favorite song of Zayn is: %s.\n", fSong);
}
}
class Zayn{
String name;
Zayn(){
this.name = this.name;
}
void makeMusic(){
System.out.println("Zayn makes music");
}
}
//superclass
class Songs extends Zayn{
Songs(){
super();
}
void makeMusic(){
System.out.println("Pillowtalk Lyrics: Pillowtalk, my enemy, my ally\n");
}
public void setName (String newName){
this.name = newName;
}
void displayName(){
System.out.println("\nName of Artist: " + this.name);
}
}
class Lyrics extends Zayn{
#Override
void makeMusic(){
System.out.println("Dusk Till Down Lyrics: I'll be with you from dusk till dawn\n");
}
}
So I don't think that will compile: public class Sample Code { as an example.
Does it follow Polymorphism
It sorta demonstrates it, but it doesn't look like a clear application of the principle.
What's a Zayn, and why is a Song a Zayn and a Lyric is a Zayn?
Polymorphism is to represent a hierarchical typing of your objects. E.g. you could have Animal as base class, with Mammal and Reptile extending. This can be further extrapolated to have Dog and Cat extend from Mammal, while Lizard and Snake extend from Reptile.
Bear in mind that if class Foo extends class Bar then any instance of Foo is also a Bar. This is sometimes called a "is-a" relationship, because in this scenario, a Foo is a Bar.
I'm not sure why, but I'm having a problem launching the code that I put together. For some reason, the code shows fatal errors when I enter a parameter within the methods. I have checked it several times but could not figure out what I did wrong.
Any advice would be appreciated.
public class songcode
{
/**
* #param args the command line arguments
*/
public class Songwriter{
private int song;
//variable for the amount of songs played
private int royalty;
//variable for the amount of payments
private int identification_number;
//id number of the song writer
public String first_name;
//string for the first name of songwriter
public String last_name;
//string for the last name of the songwriter
public int Adding_song(){
song = song + 1;
if(song > 100){
System.out.println("You are a big star!");
}
return(song);
}
public int Requesting_check(){
royalty = royalty + 10;
System.out.println("You just got payed");
return royalty;
}
public static void main(String[] args){
}
}
}
See the comments for some quick help :)
public class SongWriter {
private int song;
//variable for the number of songs played
private int royalty;
//variable for the number of payments
private int identification_number;
//id number of the song writer
public String first_name;
//string for the first name of songwriter
public String last_name;
//string for the last name of the songwriter
public SongWriter(int myFavSong){
//define default values for vars above
this.song = myFavSong;
//'This' references the Songwriter object not required but useful practice.
}
// Lower case first word upcase second : camelCase
public int addingSong(int numSongs){
song = song + numSongs;
if(song > 100){
System.out.println("You are a big star!");
}
return(song);
}
public int requestingCheck(){
royalty = royalty + 10;
System.out.println("You just got payed");
return royalty;
}
// The main method shouldn't be nested another class
public static void main(String[] args){
//In java because our variables and functions are not static
//you need a reference to your SongWrite object
SongWriter songWriter = new SongWriter();
// Notice I modified your function to take in an int as a param
songWriter.song = addingSong(5);
System.out.println(songWriter.song);
}
}
because of lack information it is a little hard for us to solve your problem. Please provide us exacly what steps did you take and what errors did you get.
From what i see now, since your are using inner class (class inside of another class), you should make it static:
static class Songwriter{/*your code here*/ }
When you got that you can create an object of that class in your main() by calling your outer class, so in your case it would be:
songcode.Songwriter name = new songcode.Songwriter();
Now you can use your methods that are within your inner class by using name.method() like:
name.Requesting_check();
for(int i = 0; i<200; i++){
name.Adding_song();
}
Personally i would create a new java file called Songwriter.java, add a constructor and work with that, but maybe that's not what you were testing here ;-)
Hope it did help you and please next time provide more detailed informations, so we can give you an exact answer without guessing what's wrong and what exacly do you want to achieve with your code.
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 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.
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( ... );
}