The question is
Write a method readStock(String[] sAr, double[] pAr, int[] qAr) to read the following details from a file named “stock.txt”.
So I created the stock file which contain
pillow 14.50 30
Sheet 43 40
Quilt 52.50 40
Set 100 200
and I do this method
public static void readStock(String[] sAr, double[] pAr, int[] qAr) throws FileNotFoundException
{
Scanner input = new Scanner(new FileReader("stock.txt")) ;
int i = 0;
while (input.hasNext())
{
sAr[i]= input.next();
pAr[i] = input.nextDouble();
qAr[i] =input.nextInt();
i++;
}
input.close();
System.out.print("ITEM"+" "+"Price"+" "+"Quantity");
for (i=0;i<qAr.length;i++)
{
System.out.println(sAr[i]+" "+pAr[i]+" "+qAr[i]+"");
}
}
but I don't know the way to call it ?
I did
public static void main(String[] args)
{
readStock();
}
}
but there is an error.
You should pass in 3 corresponding parameters, in your case they are String[] sAr, double[] pAr, int[] qAr. Therefore you should do something like readStock(sAr, pAr, qAr);
You require 3 parameters in you method signature, 3 arrays so you need to pass them to the method. You can do it like: readStock(new String[4], new double[4], new int[4]); However with this design you need to know how many lines you file contains (because you need to create arrays with proper size). To make it work with any file length just replace arrays with Lists:
public static void readStock(List<String> names, List<Double> prices, List<Integer> quantity) throws FileNotFoundException
{
Scanner input = new Scanner(new FileReader("stock.txt")) ;
while (input.hasNext())
{
names.add(input.next());
prices.add(input.nextDouble());
quantity.add(input.nextInt());
}
input.close();
System.out.print("ITEM"+" "+"Price"+" "+"Quantity");
for (int i=0; i<names.size(); i++)
{
System.out.println(names.get(i)+" "+prices.get(i)+" "+quantity.get(i)+"");
}
}
Lists have the ability to expand their size when you are adding an element and there is not enough space for him. To create new List you can use for example new ArrayList<String>()
Related
I need to write a Java program where I can read data from a file which has students names and grades. I must find the max grade for each student and then write his name and max grade in a new file. I have been able to do this. The thing is, students should be printed in decreasing order based on their max grade and I can't find out how to do that. Can you help me please? Thank you!
public class NotaMax {
public static void main(String args[]) throws FileNotFoundException{
Scanner input=new Scanner(new File("teksti.txt"));
PrintStream output=new PrintStream(new File("max.txt"));
while(input.hasNextLine()) {
String rreshti=input.nextLine();
max(rreshti,output);
}
}
public static void max(String text,PrintStream output) {
Scanner data=new Scanner(text);
String emri=data.next();
double max=0;
while(data.hasNext()) {
double nota=data.nextDouble();
if(nota>max) {
max=nota;
}
}
output.println(""+emri+":"+max);
}
}
There are two approaches for this, one filling up the other.
You can save them in an ArrayList and then call the method Array#reverse so it will reverse the ArrayList. To add another layer of certainty, it's better to make an Object/Class named Student and apply a Comparator to the #sort method of the ArrayList in order to assure the outcome.
This however takes a lot more steps than the easiest and most efficient way of tackling this problem.
What the best you could do is save the Student Object inside an ArrayList (or HashSet, really any Comparable Collection/Map) and use the #sort method to sort it from the down to the top.
I could (if requested), provide some code for this.
First thing that comes to my mind is creating a separate class for your students and implementing a simple binary heap as a maximum heap with max grade of each student as a sorting criteria. Then just printing it. Shouldn't be to hard.
This should solve your problem. First of all read students and grades in teksti.txt in an Map and then find max grade for each student.
public class NotaMax {
private static Map<String, ArrayList<Integer>> students = new HashMap<>();
private static void readTeksti() throws FileNotFoundException {
Scanner input = new Scanner(new File("teksti.txt"));
// read teksti.txt
String[] line;
while (input.hasNextLine()) {
String rreshti = input.nextLine();
line = rreshti.split(" ");
ArrayList<Integer> grades = students.get(line[0]);
if (grades == null) {
grades = new ArrayList<>();
grades.add(Integer.parseInt(line[1]));
students.put(line[0], grades);
} else {
grades.add(Integer.parseInt(line[1]));
}
}
}
public static void main(String args[]) throws FileNotFoundException {
readTeksti();
max();
}
private static void max() throws FileNotFoundException {
PrintStream output = new PrintStream(new File("max.txt"));
List<Map.Entry<String,Integer>> maximums = new LinkedList<>();
for (String current : students.keySet()) {
ArrayList<Integer> grades = students.get(current);
Integer max = Collections.max(grades);
maximums.add(new AbstractMap.SimpleEntry<>(current, max));
}
Collections.reverse(maximums);
for (Map.Entry<String,Integer> current : maximums) {
output.println("" + current.getKey() + ":" + current.getValue());
}
}
}
I assumed that teksti.txt is like :
saman 100
samad 80
samsam 70
samsam 90
saman 90
This essentially is a small code I'm writting for practice that requires me to use StringTokenizer. I've done the same kind of programs before , but now when I store the strings in an array and try to print them it show's a null pointer exception. Any help?
import java.util.*;
public class board1
{
String key;
String m[];
//function to accept the sentence
void getsent()
{
Scanner in=new Scanner(System.in);
System.out.println("Enter a sentence terminated by'.' or '?'");
String take=in.nextLine();
StringTokenizer taken=new StringTokenizer(take);
int numtokens=taken.countTokens();
String m[]=new String[numtokens];
for(int i=0;i<m.length;i++)
{
m[i]=taken.nextToken();
}
for(int i=0;i<m.length;i++)
{
System.out.print(m[i]);
}
}
// function to display
void display()
{
System.out.println("The words seperately right now are:");
for(int i=0;i<m.length;i++)
{
System.out.print(m[i]+"\t");
System.out.println();
}
}
// main to get functions
public static void main(String args[])
{
board1 ob= new board1();
ob.getsent();
ob.display();
}
}
You're shadowing the variable m. Replace
String m[] = new String[numtokens];
with
m = new String[numTokens];
I think because you are shading properties. You have an array called m into which you are putting tokens in getSent, but display is using the m array defined in the class to which you haven't added anything.
Print out the size of m in display, this will show you that you are not adding anything to the property called m.
If I have an array that gets updated as I run a program (say I ask the player for 5 numbers), call is ClassA and then want to save it using a different class, call it ClassB that imports the data from ClassA, how would I do this?
I am able to create a global variable and pass that information to ClassB but how would I pass a method that takes an argument from a different method to this file?
Here is what I have attempted so far:
class quiz
{
--- other code irrelavent to question ---
public static int[] scorearrayp1()
{
int[] scorep1 = new int[4]; // this creates the array that gets filled later
return new int[4];
}
public static void askQ(scorep1)
{
JOptionPane.showInputDialog("Some numbers");
// this method then fills the array depending on user input
// it is the values from here that I wish to save in classB
}
public static int[] passArray(int[] scorep1)
{
return scorep1; // this is from class A and takes the value from a method before
}
And this is the class I want to send this array to:
class saveScores
{
public static void main(String[] params) throws IOException
{
PrintWriter outputStream = new PrintWriter(new FileWriter("scores.txt"));
finalproject data = new finalproject();
int[] scores = data.passArray(int[] scorep1);
for (int i = 0; i < scores.length; i++)
{
outputStream.println(scores[i]);
}
outputStream.close();
System.exit(0);
}
}
At the moment I'm being thrown two errors
error:'.class' expected
int[] scores = data.passArray(int[] scorep1);
^
error:';' expected
int[] scores = data.passArray(int[] scorep1);
^
I had the idea to change passArray(int[] scorep1) to passArray(scorep1) but then it just tells me that the symbol cannot be found.
Change
int[] scores = data.passArray(int[] scorep1);
to
int[] scores = data.passArray(scorep1);
But still you will need to declare scorep1, for example like:
int[] scorep1 = new int[]{1, 0, 0}
According to your edited question (and if I understand right), your code should look like the following:
int[] scores = quiz.passArray(quiz.scorearrayp1());
Anyway, please keep in mind that class names should always be uppercase.
You can do something like this:
class quiz{
int[] scorep1 = null;
public quiz()
{
scorep1 = new int[4]; // this creates the array that gets filled later
}
public static int[] askQ()
{
JOptionPane.showInputDialog("Some numbers");
// here call fills the array depending on user input
}
And do this:
int[] somearray = quiz.askQ();
int[] scores = data.passArray(somearray);
You should create an array somearray like above to pass at the method data.passArray(somearray);
I'm running out of patience and needs this problem fixed. This program is intended to retrieve data from two text files as two string arrays, then use a mergesort algorithm to sort the results. My issue is during the conversion to an integer array. I return the array I created, and see that there is data stored. However, when running an loop and checking if any index is null, I find that the program believes them all to be null.
import java.io.IOException;
import java.nio.file.Files;
import java.io.File;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.*;
public class MergeInventories
{
public static File inv1 = new File("H:\\Senior Year\\CompSci\\Projects\\storeOneInv.txt");
public static File inv2 = new File("H:\\Senior Year\\CompSci\\Projects\\storeTwoInv.txt");
//the two text files I'm retrieving data from
public static String[] store1; //string array in question
public static String[] store2;
public static void header()
{
System.out.println("Keenan Schmidt");
System.out.println("AP Computer Science");
System.out.println("Merge Inventories");
System.out.println("...finally...");
}
public static void main() throws FileNotFoundException
{
header();
readFiles(inv1,store1); //converts file to string array
sort(); //converts string[] to int[]
//System.out.print(readFiles(inv1,store1));
//System.out.print(readFiles(inv2,store2);
}
public static String[] readFiles(File file, String[] store)
{
try {
Scanner scanner = new Scanner(file);
int i = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
scanner = new Scanner(file);
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
i++;
}
store = new String[i];
i = 0;
scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
store[i] = line;
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return store;
}
public static int[] sort()
{
int[] items = new int[store1.length];
for(int i = 0; i < store1.length; i++)
{
if(store1[i] != null) //this is the line where the error occurs
{
try{
items[i] = Integer.parseInt(store1[i].replaceAll("[^0-9]"," "));
} catch (NumberFormatException nfe) {};
}
}
return items;
}
private void mergeSort(String[] arr1, String[] arr2)
{
}
private void merge(int low, int med, int hi)
{
}
}
As azurefrog mentions in a comment, Java arrays are pass by value (the reference to the array) so that when you reassign the store variable in the method, the original array you passed in doesn't get the new reference assignment.
Since you want to re-use this method multiple times to make different arrays, I would suggest making a new array everytime inside the method. No need to pass it in.
static String[] readFiles(File file){
String[] store =null;
//rest of method this same
}
Then in your calling code:
store1 = readFiles(inv1);
store2 = readFiles(inv2);
You are getting a NullPointerException when trying to access store1 because you never give store1 a value other than null, because Java is pass-by-value.
You create a new array, but you only assign it to store, which is a local variable in readFiles(), and that assignment has no effect on the store1 variable.
You do return that value from your method, but you neglected to assign it in the invoking code.
Replace
readFiles(inv1,store1); //converts file to string array
with
store1 = readFiles(inv1,store1); //converts file to string array and saves it in store1
so that the created array is assigned to store1.
As dkatzel points out, this means that there is no longer any point in passing store1 into the method in the first place. It would be a good idea to follow his advice on cleaning up the method.
You can use a List at first because the file could be of unknown size, then convert the List to an Array (using toArray), and then you will know the length to which you should initialize the int array and your code can proceed as expected.
either change to this: store1 = readFiles(inv1,store1);
or in readFiles() use this.store1 instead
I'm having trouble with calling a method. The basis of the program is to read in data from data.txt, grab the name token given, then all of the grades that follow, then implement some operations on the grades to give details of the person's grades. I do all of the methods in a separate file named Grades.java, which has the Grades class. I'm just having trouble because I MUST have the testGrades method in my code (which I don't find necessary). I have done everything I need to do for the results to be perfect in a different program without having two different .java files. But it's necessary to do it this way. I think I have mostly everything pinned down, I'm just confused on how to implement and call the testGrades method. I commented it out and have the question on where it is in the program. Quite new to classes and objects, and java in general. Sorry for the lame question.
public class Lab2 {
public static void main(String[] args) {
Scanner in = null; //initialize scanner
ArrayList<Integer> gradeList = new ArrayList<Integer>(); //initialize gradeList
//grab data from data.txt
try {
in = new Scanner(new File("data.txt"));
} catch (FileNotFoundException exception) {
System.err.println("failed to open data.txt");
System.exit(1);
}
//while loop to grab tokens from data
while (in.hasNext()) {
String studentName = in.next(); //name is the first token
while (in.hasNextInt()) { //while loop to grab all integer tokens after name
int grade = in.nextInt(); //grade is next integer token
gradeList.add(grade); //adding every grade to gradeList
}
//grab all grades in gradeList and put them in an array to work with
int[] sgrades = new int[gradeList.size()];
for (int index = 0; index < gradeList.size(); index++) {
sgrades[index] = gradeList.get(index); //grade in gradeList put into grades array
}
//testGrades(sgrades); How would I implement this method call?
}
}
public static void testGrades(Grades grades) {
System.out.println(grades.toString());
System.out.printf("\tName: %s\n", grades.getName());
System.out.printf("\tLength: %d\n", grades.length());
System.out.printf("\tAverage: %.2f\n", grades.average());
System.out.printf("\tMedian: %.1f\n", grades.median());
System.out.printf("\tMaximum: %d\n", grades.maximum());
System.out.printf("\tMininum: %d\n", grades.minimum());
}
}
This is a little snippet of the beginning of the Grades.java file
public class Grades {
private String studentName; // name of student Grades represents
private int[] grades; // array of student grades
public Grades(String name, int[] sgrades) {
studentName = name; // initialize courseName
grades = sgrades; // store grades
}
public String getName() {
return studentName;
} // end method getName
public int length() {
return grades.length;
}
well your test grades take a Grades object so you need to construct a Grades object using your data and pass it to your test grades method
i.e.
Grades myGrade = new Grades(studentName,sgrades);
testGrades(myGrade);
It looks like what you need to do is have some type of local variable in your main method, that would hold your custom Grade type. So you need add a line like..
Grades myGrades = new Grades(studentName, sgrades);
Then you can call your testGrades method with a line like...
testGrades(myGrades);
Looks like you may also need a toString method in your Grades class.
Seems like homework, so I tried to leave a bit to for you to figure out :)