Advice on Java class - java

I am starting Java class and this is my first code, so please be gentle ;)
//importing libraries
import java.io.*;
import javax.swing.*;
public class SongCollection {//class
//declaring arrays to hold user inputs
static String title[]={"","",""};
static String artist[]={"","",""};
static double length[]={0,0,0};
static int arrayindex=0;//declaring an index to keep track of arrays
public static void main(String[] args) throws IOException{//main method
menu();//calling menu method
}
public static void menu() throws IOException{//menu method
String s=JOptionPane.showInputDialog("Choose a menu option\n" +//taking user input and storing it into a string
"1: Add Song\n" +
"2: Search for a song\n" +
"3: Edit a song\n" +
"4: Sort songs\n" +
"5: Print songs\n" +
"6: Save songs to file\n" +
"7: Read songs from file\n" +
"8: Exit");
int menu=Integer.parseInt(s);//converting user input into a number
switch(menu){//going to the appropriate method depending on what number the user presses on the keyboard
case 1: add(); break;
case 2: search(); break;
case 3: edit(); break;
case 4: sort(); break;
case 5: print(); break;
case 6: tofile(); break;
case 7: fromfile(); break;
case 8: System.exit(0); break;
default: JOptionPane.showMessageDialog(null,"Please choose a valid option"); break;
}
}
public static void add() throws IOException{//add method
if(arrayindex>=title.length){//checking if the array is full
JOptionPane.showMessageDialog(null,"Song collection is full");
menu();
}
//taking the user input and storing them into variables
String newtitle=JOptionPane.showInputDialog("Enter the song title:");
String newartist=JOptionPane.showInputDialog("Enter the artist of the song:");
String s=JOptionPane.showInputDialog("Enter the length of the song:");
double newlength=Double.parseDouble(s);//converting length into a number
//taking the variables and storing them in the arrays
title[arrayindex]=newtitle;
artist[arrayindex]=newartist;
length[arrayindex]=newlength;
arrayindex+=1;//incrementing one to the array index because one new entry was added
menu();
}
public static void search() throws IOException{//search method
String key=JOptionPane.showInputDialog("Enter your search key: ");//taking in the users search key
for(int i=0; i<title.length; i++){
if(key.equals(title[i]) || key.equals(artist[i]) || key.equals(length[i])){//checking if the key is in any of the arrays
JOptionPane.showMessageDialog(null,title[i]+", "+artist[i]+", "+length[i]);//printing out the found key
menu();
}
}
JOptionPane.showMessageDialog(null,"Key not found");//if the loop completes the key doesnt exist
}
public static void edit() throws IOException{//edit method
String s=JOptionPane.showInputDialog("Which entry do you want to edit. Enter a whole number between 0 and " + (arrayindex-1));//asking the user which entry they want to edit
int edit=Integer.parseInt(s);//converting user input into a number
if(edit>arrayindex || edit<0){//checking if they enter a valid entry that can be editted
JOptionPane.showMessageDialog(null,"The entry you entered is does not exist");
menu();
}
//taking new entries from the user
String newtitle=JOptionPane.showInputDialog("Enter the new song title:");
String newartist=JOptionPane.showInputDialog("Enter the new artist of the song:");
String s2=JOptionPane.showInputDialog("Enter the new length of the song:");
double newlength=Double.parseDouble(s2);
//storing them into the array replacing what was previously stored in that index
title[edit]=newtitle;
artist[edit]=newartist;
length[edit]=newlength;
menu();
}
public static void sort(){//sort method
//nested loop to loop through all elements and make swap when needed
for(int i=0; i<title.length-1; i++)
{
for (int i1=0; i1<title.length-1; i1++)
{
//storing title current index and title next into 2 different variables
String t1 = title[i1];
String t2 = title[i1 + 1];
//storing artist current index and artist next index into 2 different variables
String a1 = artist[i1];
String a2 = artist[i1 + 1];
//storing length current index and length next index into 2 different variables
double l1 = length[i1];
double l2 = length[i1 + 1];
//comparing title current index with title next index using the compareto method
if ((t1).compareTo(t2) > 0)
{
//creating a temporary variable to store the first variable and then swapping the 2 around
String t3 = t1;
title[i1] = t2;
title[i1 + 1] = t3;
String a3 = a1;
artist[i1] = a2;
artist[i1 + 1] = a3;
Double l3 = l1;
length[i1] = l2;
length[i1 + 1] = l3;
}
}
}
}
public static void print() throws IOException{//print method
//looping through and printing out each element
for(int i=0; i<title.length; i++)
{
JOptionPane.showMessageDialog(null,title[i]+","+artist[i]+","+length[i]);
}
menu();
}
public static void tofile() throws IOException{//tofile method
final FileWriter fw=new FileWriter("SongCollection.txt");//declaring filewriter
final BufferedWriter bw=new BufferedWriter(fw);//delcaring buffer
final PrintWriter pw=new PrintWriter(bw);//declaring print writer
//looping through array
for(int i=0; i<title.length; i++)
{
pw.println(title[i]+","+artist[i]+","+length[i]);//using print writer to write all 3 elements on one line
}
pw.close();//closing the writer
menu();
}
public static void fromfile() throws IOException{//from file method
final FileReader inf=new FileReader("SongCollection.txt");//declaring file reader
final BufferedReader ib=new BufferedReader(inf);//declaring buffer reader
String s;//string to hold read lines from file
while((s=ib.readLine())!=null)//looping through the file while the lines are not empty
{
JOptionPane.showMessageDialog(null,s);//outputting the read in data to the screen
}
}
}
I have a couple of questions:
How do I make the Add Song interface have a button to go back to the main menu? similar of the other interfaces?

This is a classic neophyte mistake: your class is doing far too much. Break things up a bit.
Have a Song class that encapsulates things together:
package model;
public class Song {
private String title;
private String author;
private int length;
// You add the rest.
}
Don't use arrays of primitives; use Java collections instead.
Separate out the UI stuff from the model class. Make it possible to change UI without rewriting all your code.

You really should use a Vector or ArrayList, rather than those String[] arrays. Otherwise, you're basically saying that the user cannot possibly enter more than three inputs. Even if they could, either you would have to resize your array or you would have arrayoutofbounds exceptions.
By declaring a Vector or ArrayList, you can just keep adding elements (whilst you still have available memory) and it guards against the array out of bounds exceptions you could incur with a primitive string array.

Related

When I run my methods it keeps repeating itself and doesn't move on java

Like the caption said the method "scanInput1" runs two times in a row when it should only run once. Then the method "arrayskapare" runs as intended but after that. instead of running the method "medelvarde" is jumps back and runs "scanInput1" again and again and again
import java.util.*;
class Heltalshanterare{
private static String scanInput1(){
System.out.print("Skriv in antal heltal: ");
Scanner scr = new Scanner(System.in);
String antalHeltal = scr.next();
try {
Integer.parseInt(antalHeltal);
}
catch (NumberFormatException e) {
System.out.println("Ogilitigt värde");
scanInput1();
}
return antalHeltal;
}
private static List<Integer> arrayskapare() {
int antalangivnatal = Integer.parseInt(scanInput1());
int noll = 1;
int heltal = 0;
String tal1 = "";
Scanner tal = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
while (noll <= antalangivnatal) {
noll++;
heltal++;
System.out.print("ange heltal " + heltal + ": ");
tal1 = tal.next();
try {
int num = Integer.parseInt(tal1);
list.add(num);
} catch (NumberFormatException e) {
System.out.println("Ogiltigt värde");
noll--;
heltal--;
}
}
return list;
}
public static int medelvarde(){
int antalsiffror = arrayskapare().size();
int sum = 0;
for (int i : arrayskapare()){sum += i;}
int medelvärde = sum / antalsiffror;
System.out.println("medelvärdet av dina tal är " + medelvärde);
return medelvarde();
}
public static void main(String [] args){
scanInput1();
arrayskapare();
medelvarde();
}
}
Im sorry that the code is so long but I have been struggling with this for too long and I really need some help.
Your main method is calling each method just once, which is what you need. But it's not actually holding onto any of the values being returned. So the number of heltal (integers in English) is captured from the user but then never actually stored anywhere. And later an array of numbers is captured but not stored anywhere.
Your second, bigger problem is that your methods are then calling the earlier methods all over again. So instead of asking the user to type in the data just once, you're forcing them to answer the exact same questions multiple times.
A much tidier approach is to alter your methods so that they take the required data as a parameter. Which means your arrayskapare (array producer) method should take the antalHeltal (number of integers) value as a parameter, and then it won't need to call the scanInput1 method again. Same thing can be done for your medelvarde (mean value) method: have it take the array as a method parameter, so that it won't need to call arrayskapare.
With those changes your main method can simply look like this:
public static void main(String [] args){
int antalHeltal = scanInput1();
List<Integer> heltalArray = arrayskapare(antalHeltal);
int medelvardet = medelvarde(heltalArray);
System.out.println("Medelvärdet är " + medelvardet);
}
Now each method just gets called once and the data captured from the user gets stored into variables and passed along the river of methods until the final result is reached.

How can I stop a method updating an array outside of it

Hoping for some help - I've been asked to write a hotel room system using methods for uni. All has been going well until I try to order the array alphabetically.
I have managed to get it to order within the method but it updated the main array (hotel). I want it to keep it within the order method, if that makes sense?
I've included a cut down version below without all the functions.
Currently it will reorder the array hotel so if you view the rooms the array will print like 'e,e,e,etc, George, Peter, Robert' instead of keeping its original form 'e, Robert, Peter, e,e,etc, George'
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String roomName;
int roomNum = 0;
String[] hotelRef = new String[12];
String[] hotel = new String[12];
initialise(hotel); //initialise
while (roomNum < 13) {
System.out.println("Please select from the menu:");
System.out.println("V : View rooms");
System.out.println("O : Order Guests alphabetically");
String selection = input.next();
switch (selection) {
//There are more switch cases on the original version
case "O":
order(hotel);
break;
default:
System.out.println("");
}
}
}
private static void order(String[] hotelRef) {
int j;
boolean flag = true; //will determine when the sort is finished
String temp;
String[] order = new String[12];
order = hotelRef;
while (flag) {
flag = false;
for (j = 0; j < order.length - 1; j++) {
if (order[j].compareToIgnoreCase(order[j + 1]) > 0) {
//ascending sort
temp = order[j];
order[j] = order[j + 1]; // swapping
order[j + 1] = temp;
flag = true;
}
}
}
for (int y = 0; y < order.length; y++) {
if (!order[y].equals("e")) {
System.out.println("Room " + y + " is occupied by " + order[y]);
}
}
System.out.println("Ordering completed");
}
You should clone the hotelRef instead of assigning the reference like this order = hotelRef;
You could do the following while creating the order array :
String[] order = new String[hotelRef.length]; // to make sure that order has the right size.
and instead of order = hotelRef;
for (int i=0;i<order.length;i++)
order[i]=hotelRef[i]; // thereby cloning
or use System.arraycopy() or any other method to accomplish cloning the array.
You can make copy of hotel array in your order method:
String[] hotelCopy = new String[hotelRef.length];
System.arraycopy(hotelRef, 0, hotelCopy, 0, hotelRef.length);
And then just use hotelCopy inside your order method.
The problem lies with the following line
order = hotelRef;
Change it to
order = hotelRef.clone();
Though you are creating a new object, you have assigned the reference to outer object only. So whatever changes you make in the inner object it will be reflected to the outer object.

Beginner at Java through APCS first post. Is my Java program actually executable after compiling correctly? I think I may be somehow stuck in a loop

This chapter of the course is teaching us about methods in Java, more specifically returning values. While the rubric called for it to just be able to apply values from a .txt list the 9 planets provided below the program. I wanted to go beyond and make it so that there would be no limit on the amount of celestial bodies this could apply to (as I did with the program that created the .txt as an output). I have a finished program by another student available to me. However, I'd rather try approaching it in another way(Though I must thank Omar because I had no idea you could return arrays from methods).
Currently, as is, the program compiles without any errors in BlueJ. However, It does not run, or even put out any test print statements I put in. It's been running for over an hour on core 2 of my overclocked i5, but nothing. Since the core is being stressed, I assume it's stuck in a loop somehow?
How may I solve this issue?
I really appreciate any advice, and hope to spend more time here in the future.
/**
* 7.04 This program will take gravity and textual data from a .txt
* and will perform calculations with it once I figure out how that may be done.
*
*
* #author ********
* #version (The Date)
*/
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class Weight2
{
// write static methods here
// Note: formula for finding weight on a planet: Earth weight divided by Gravity constant times surface gravity
public static String[] getData(int arraylength,int i, int value) {
String [] Gravityscan = new String[arraylength]; //Initiates String Arrays to be used
String [] pregravity = new String[arraylength];
String [] names = new String[arraylength];
String [] prevalues = new String[arraylength];
String [] error = {"error"};
String delims = "[ |\\ ]+"; // Sets Delimiters
File data2 = new File("Gravityoutput.txt"); //Opens data source
Scanner inFile = new Scanner("Gravityoutput.txt");
for(int m = 0; m < arraylength ; m++)
{
Gravityscan[m] = inFile.nextLine(); //String for each line being run
prevalues = Gravityscan[m].split(delims); //Split into two (gravity name)
pregravity[m] = prevalues[0]; //Sorts gravity string to array
names[m]= prevalues[1]; //Sorts name string to array
}
inFile.close();
//if (value == 0){return Integer.toString(arraylength);}
if (value == 1){return pregravity;} //Returns pregravity string for first part of loop below
else if (value == 2){return names;} //Returns names to end of for string below
else {System.out.print("AN ERROR HAS OCCURED IN METHOD GETDATA"); return error;}
}
//public static double calcWeight() {
//}
public static void main(String[] args)throws IOException
{
Scanner in = new Scanner(System.in);//Scanner activated
File data = new File("Gravityoutput.txt"); //Select file to get data from
Scanner inFile = new Scanner("Gravityoutput.txt");
int arraylength = 0; //Works with loop to determine length of data
while (inFile.hasNext())
{
arraylength++;
}
inFile.close(); //Closes file
System.out.print("arraylength is " + arraylength);//Beta testing check
double [] gravities = new double[arraylength]; //Declaring double array for after string conversion
//String[] names = new String[arraylength]; //Declaring array to be used for names
System.out.print("Please enter your mass on Earth in lbs: "); //User input for math
double earthWeight = in.nextDouble();
for(int i=0; i < arraylength; i++)
{
int value = 1;
String[] stringgravity = getData(arraylength, i, value);
gravities[i] = Double.parseDouble(stringgravity[i]);
System.out.print(gravities[i] + " gravity ");
value++;
String[] names = getData(arraylength, i, value);
System.out.println(names[i] + "gravity");
// static method you write Double.parseDouble
}
//double[] weight = calcWeight(earthWeight, gravity); // static method you write
//printResults(names, gravity, weight); // static method you write
} //end main
}//end class
//Below is the data contained by Gravityoutput.txt
3.70 Mercury
8.87 Venus
9.82 Earth
3.70 Mars
24.78 Jupiter
10.44 Saturn
8.86 Uranus
11.13 Neptune
0.61 Pluto
Creating an instance of Scanner with Scanner inFile = new Scanner("Gravityoutput.txt"); does not read input from the file, it reads input from the String "Gravityoutput.txt".
Try Scanner inFile = new Scanner(data); instead.
Oh, and your code is stuck in a loop :
inFile.hasNext() always returns true, since you never read anything from the Scanner.
You can replace it with
while (inFile.hasNext())
{
String str = inFile.next();
arraylength++;
}

Sorting an array of students by last name alphabetically in Java

I currently have this program read the contents of a text file and calculate the averages and amount of test scores taken and print them out neatly in a small data table. These are the names, amount of quizes taken and average of each student:
James Tiberius Kirk 8 91.63
Buffy Summers 7 83.14
Tom Baker 15 100.00
Malcolm Reynolds 9 84.22
Elizabeth Bennet 9 93.33
John Blutarsky 9 0.00
Dorthy Gale 6 85.83
All of these Students are stored within the Array named Anames[]. I was wondering if it was at all possible to sort these students alphabetically by last name using the code that I have now. When I run the program it gives me the error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1927)
at text.reader.TextReader.compareLastNames(TextReader.java:117)
at text.reader.TextReader.main(TextReader.java:94)
Here is the code of my main class:
public static void main(String[] args)throws IOException{
Double score=0.0;
int b,j;
String tempfirst = "";
String templast = "";
Student Anames[] = new Student[30];
Student Temp[] = new Student [1];
int Stucount = 0;
Scanner reader = new Scanner(new File("quizScores.txt"));
boolean runProgram = true;
PrintWriter writer = new PrintWriter(new File("scoreReport.txt"));
//prints header for report
System.out.println("Name Number Quizes Quiz Socres");
writer.println("Name Number Quizes Quiz Socres");
//check to see if end of file string
while (!reader.hasNext("-10")){
String name="", first="", last="";
//gets the name from file
while(!reader.hasNextDouble()){
last = reader.next();
while (!reader.hasNextDouble()){
first = first+reader.next()+" ";
}
name=first+last;
}
//creates new student with given name
Student newStudent = new Student(first, last);
Anames[Stucount] = newStudent;
Stucount++;
//gets the quiz scores and makes sure does not averge in the end of file string.
while (reader.hasNextDouble()&& !reader.hasNext("-10")){
newStudent.addQuiz(reader.nextDouble());
}
//Prints out the formated data
System.out.printf("%-30s%4.0f%30.2f \n",newStudent.getName(), newStudent.getQuizNumber(), newStudent.getAverage());
writer.printf("%-30s%4.0f%30.2f",newStudent.getName(), newStudent.getQuizNumber(), newStudent.getAverage());
writer.println();
}
System.out.println("\n");
for (b = 0; b < Stucount; b++){
int INTEGERTEMP = b;
for (j= b+1; j < Stucount; j++){
int INTEGERTEMP2 = j;
if ((compareLastNames(Anames[INTEGERTEMP].getLAST(), Anames[INTEGERTEMP2].getLAST()))>0){
Temp[0] = Anames[b];
Anames[b] = Anames[j];
Anames[j] = Temp[0];
}
}
}
System.out.println("Name Number Quizes Quiz Socres");
for (int i = 0; i < Stucount; i++) {
System.out.printf("%-30s%4.0f%30.2f \n", Anames[i].getName(), Anames[i].getQuizNumber(), Anames[i].getAverage());
}
writer.close();
}
private static int compareLastNames(String a, String b){
int index_a = a.lastIndexOf(" ");
String surname_a = a.substring(index_a);
int index_b = b.lastIndexOf(" ");
String surname_b = b.substring(index_b);
int lastNameCmp = surname_a.compareToIgnoreCase(surname_b);
return lastNameCmp;
}
Here is the Student.java which contains most of the methods used:
public Student (String inName, String inLast){
studentName=inName;
studentLast = inLast;
quizAverage = 0;
quizScore=0;
numberQuizes=0;
}
public void addQuiz(double inQuiz){
quizScore += inQuiz;
numberQuizes++;
}
public double getAverage(){
quizAverage = quizScore/numberQuizes;
return quizAverage;
}
public String getName(){
return studentName+studentLast;
}
public double getQuizNumber(){
return numberQuizes;
}
public String getLAST(){
return studentLast;
}
You can use java.util.Arrays.sort(Student [] arr, Comparator<Student> comp) instead of your own compare code. In single line you can achieve it like this:
Student arr[];//considering this array you will populate
Arrays.sort(arr,new java.util.Comparator<Student>(){
public int compare(Student o1, Student o2) {
return o1.studentLast.compareTo(o2.studentLast);
}
});
//then the arr will be sorted with studentLast name
Let's work our way back from your exception to figure out where the problem is. First, it tells us we've got a StringIndexOutOfBoundsException on line 117; that is, the line (it might actually be the surname_b line, you've removed code from the class that means I can't match up the lines properly)
String surname_a = a.substring(index_a);
You'll notice the message from the exception helpfully tells us that the index used was -1. Let's take a look at why a.lastIndexOf(" "); would return -1. We see in the documentation for String that it returns -1 when the character does not occur in the String.
Now, let's work another step back in the Exception's stack trace to figure out why there's no space in that String. The Exception tells us to check line 94, where we see
if ((compareLastNames(Anames[INTEGERTEMP].getLAST(), Anames[INTEGERTEMP2].getLAST()))>0){
So, what's going on here? We're passing in the last names (and just the last names) from each of the students into our comparison function. The last names, for the most part, have no spaces in them.
So, how do we fix this? Well, you'll have to change your function to only take substrings of the surname if there actually is a space in them, i.e. if the index returned isn't -1.
Once you've got the comparison function done, I recommend looking at how to write an Object that implements the Comparable interface. This will allow you to use library sorting functions, which will be faster and less buggy than your own sorting functions (most likely!).

Java 2D ArrayList

so every time i run the program and enter the 2nd choice, it tells me rangecheck error , index0 , size 0.
what i understand from this after research is that the arraylist is empty, how do i use the add function in the 2D arraylist?
|ABCDEFGHIJKLMNOPQRSTUVWX
--+------------------------
01|gggggggggggggggggggggggg
02|gGGGGGGGGGGGGGGGGGGGGGGg
03|gGggggggggggggggggggggGg
04|gGgYYYYYYYYYYYYYYYYYYgGg
05|gGgYggggggggggggggggYgGg
06|gGgYggggggggggggggggYgGg
07|gGgYggYYYYYYYYYYYYggYgGg
08|gGgYggYggggggggggYggYgGg
09|gGgYYYYggggggggggYYYYgGg
10|gGggggggggggggggggggggGg
11|gGGGGGGGGGGGGGGGGGGGGGGg
12|gggggggggggggggggggggggg
package map;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Scanner;
import java.util.ArrayList;
public class MapMain
{
public static void main(String [ ] args)
{
Scanner input = new Scanner(System.in);
InputStream is = null;
int i;
char c;
String T;
ArrayList<ArrayList<String>> Contain = new ArrayList<ArrayList<String>>();
for(int L = 0; L < 30; L++)
{
Contain.add(new ArrayList<String>());
}
try{
do{
int a=0;
String Elements;
System.out.print("To load map enter 1\nTo print loded map enter 2\nTo change specific elements press 3 ");
a=input.nextInt();
switch (a){
case 1 :
System.out.print("What is the file dest?");
T=input.nextLine();
is = new FileInputStream(T);
while((i=is.read())!=-1)
{
c=(char)i;
String O = "ankosh";
//Contain.add(Contain.O);
}
break;
case 2:
while(true)
{
String U = Contain.get(16).get(0);
//System.out.print(Contain);
break;
}
break;
case 3:
System.out.print("What do you want to insert?");
Elements=input.nextLine();
//switch (Elements){
//case
}
break;
} while(true);
}catch(Exception e){
// if any I/O error occurs
e.printStackTrace();
}finally{
}
}
}
You created the array of arrays, and the arrays it contains, so far it's ok.
Now, on case 2 you are trying to reach the first element of the 16th array (basically of type String) which is null since you didn't add anything yet to this array.
What you need to do before trying the get(index), is to check that the length of the array is bigger than the index.
In order to add to the array:content.get(16).add(str);.

Categories

Resources