I can't exactly figure out what the issue is. I think it has to do with the array list but I'm not quite sure how to fix this. I've tried to instead of returning the array list, add to a new array list created in the main function but that didn't work. The error I keep getting is:
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at fileAnalyze.inputFileList(fileAnalyze.java:18)
at fileAnalyze.main(fileAnalyze.java:6)
import java.util.*;
import java.io.*;
public class fileAnalyze {
public static void main(String[] args){
ArrayList<Integer> inputFileInfo = inputFileList("inputFile.txt");
int count = numberAmount(inputFileInfo), small = inputFileInfo.get(argmin(inputFileInfo)),
big = inputFileInfo.get(argmax(inputFileInfo)), theAverage = average(inputFileInfo);
fileCreate(count, small, big, theAverage);
}
private static ArrayList <Integer> inputFileList(String n){
Scanner reading = new Scanner(n);
ArrayList<Integer> inputFileData = new ArrayList<Integer>();
while (reading.hasNextLine()){
int data = reading.nextInt();
inputFileData.add(data);
}
reading.close();
return inputFileData;
}
private static int numberAmount(ArrayList<Integer> n1){
return n1.size();
}
private static int argmin(ArrayList<Integer> n2){
int arg= -1, x = 0;
for (int i = 0; i < n2.size(); i++){
if (n2.get(i) < x){
arg = i;
x = n2.get(i);
}
}
return arg;
}
private static int argmax(ArrayList<Integer> n3){
int arg= -1, x = 0;
for (int i = 0; i < n3.size(); i++){
if (n3.get(i) < x){
arg = i;
x = n3.get(i);
}
}
return arg;
}
private static int average(ArrayList<Integer> n4){
int total = 0;
for (int i = 0; i < n4.size(); i++){
total = total + n4.get(i);
}
int average = total / n4.size();
return average;
}
private static void fileCreate(int numberCount, int minNum, int maxNum, int avg){
try {
File outputFile = new File("outputFile.txt");
if (outputFile.createNewFile()) {
}
else {
System.out.println("File already exists");
}
FileWriter writing = new FileWriter("outputFile.txt");
writing.write("**********");
writing.write("There are " + Integer.toString(numberCount) + " numbers in this file.");
writing.write("The minimum number is " + Integer.toString(minNum));
writing.write("The maximum number is " + Integer.toString(maxNum));
writing.write("The average is " + Integer.toString(avg));
writing.close();
} catch (IOException e){
System.out.println("An error has occured.");
e.printStackTrace();
}
}
}
I would change your code to
while (reading.hasNextLine()){
String line = reading.nextLine ();
try{
Integer data= Integer.valueOf(line);
inputFileData.add(data);
}
catch (NumberFormatException ex){
ex.printStackTrace();
}
}
This will allow you to read your file even if it has blanks lines or other non-integer junk
Refer the official docs:
InputMismatchException - if the next token does not match the Integer regular expression, or is out of range
So either ensure your input is a legal int value or add the try/catch clause.
Problem:
Here : int data = reading.nextInt();
You are trying to get an Integer from the file but a file may contain characters and not just integers.
Solution:
To make sure you read only integer from the file, you need to catch an expection if the file contains a non desirable input.
Change this line :
int data = reading.nextInt();
To:
try {
int data = reading.nextInt();
catch(InputMismatchException e) {
//Your code for handing exception.
}
Related
I have a function that is searching for max number in the array. I want to make the function to search for more than one word that is entered from console.
As example I enter two words(car,ride) they're added to array and then "surasti" function is comparing them if they're in the array.
I have tried to do it on my own, but I'm a started and it seems too hard :(
Function that is searching:
public static produktas[] surasti (produktas G[], int n){
produktas A[] = new produktas[1];
produktas max = G[0];
for (int i=1; i<n; i++)
if (max.gautiSvori()<G[i].gautiSvori()) max = G[i];
A[0]=max;
return A;
}
The code that is calling that function (A is the array that you have to search in.):
case 5:
B = surasti(A, n);
System.out.println("Sunkiausias gyvunas yra:");
spausdinti_sar_ekrane(B, B.length);
break;
The produktas class:
class produktas {
private String pavadinimas;
private String salis;
private Double svoris;
private Double kaina;
produktas() {}
produktas(String pav, String salis, double svoris, double kaina){
pavadinimas = pav;
this.salis = salis;
this.svoris = svoris;
this.kaina = kaina;
}
public String gautiPav (){
return pavadinimas;
}
public String gautiSali (){
return salis;
}
public double gautiSvori (){
return svoris;
}
public double gautiKaina (){
return kaina;
}
}
When I try to change the function to this (don't know if its working fine, can't test it):
public static produktas[] surasti (produktas G[], int n){
try{
BufferedReader in = new BufferedReader (new InputStreamReader (System.in));
produktas A[] = new produktas[5];
for (int j=0; j<5; j++){
System.out.println("Kokio produkto ieskosime?");
String found = in.readLine();
for (int i=1; i<n; i++){
if (found.equals(G[i].gautiPav())){
A[j] = G[i];
}
}
}
return A;
} catch(IOException ie){
ie.printStackTrace();
}
}
When I try this code I get this error at public static produktas[] surasti (produktas G[], int n){ line:
This method must return a result of type produktas[]
For the correctly complied code update your method to have a return in catch block as well.
public static produktas[] surasti(produktas G[], int n) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
produktas A[] = new produktas[5];
for (int j = 0; j < 5; j++) {
System.out.println("Kokio produkto ieskosime?");
String found = in.readLine();
for (int i = 1; i < n; i++) {
if (found.equals(G[i].gautiPav())) {
A[j] = G[i];
}
}
}
return A;
} catch (IOException ie) {
ie.printStackTrace();
return null; // Expected return from catch block
}
}
To understand the issue properly start using IDE like eclipse rather than simply using a notepad and compiling code through java/javac
A more suitable code would be like as below. Type q in console when u want to exit from the program.
public static produktas[] surasti(produktas G[], int n) {
BufferedReader consoleReader = null;
produktas produktasFound[] = new produktas[5]; // Initalize array to store the produkt found
try {
consoleReader = new BufferedReader(new InputStreamReader(System.in));
boolean exit = false;
produktas produktasFound[] = new produktas[5];
int j = 0;//current produktFound index
while (!exit) {
System.out.println("Kokio produkto ieskosime?");
String produktPav = in.readLine();
if ("q".equals(produktPav)) {
exit = true;
} else {
for (int i=1; i<n; i++){
if (found.equals(G[i].gautiPav())){
A[j] = G[i];
j++;
}
}
}
if(j == 5)
exit = true;
}
return produktasFound; // return all the 5 produktas found
} catch (IOException e) {
e.printStackTrace();
} finally {
if (consoleReader != null) {
try {
consoleReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return produktasFound; //If no produkt is found from the array returned is blank
}
Your comparison operator is not correct. Try the following code :
public static produktas surasti(produktas G[]) {
produktas max = G[0];
for (int i = 0; i < G.length; i++) {
if (max.gautiSvori() < G[i].gautiSvori()) {
max = G[i];
}
}
return max;
}
You need to pass the array and set the first element of the array as the maximum as by default first. Next iterate through the array and check whether there is a produktas with a higher value of svoris. If so, change the max to point to this new produktas. At the end of the for loop, you will now have the max set to the produktas with the highest value of svoris.
There are few things in the code that you can fix for better quality code.
You don't need to pass the array size to the surasti method. We can just do a G.length (in the code above I have done that).
Best practice is to user Camel case for Java classes. Therefore instead of produktas, use Produktas
Use meaningful names for variables instead of A, G, etc
I'm making a program that reads some data from a text file and then takes that data and finds the minimum, maximum, and average of the numbers. For some reason I'm getting a lot of ridiculous errors I've never seen before. Here is my code:
import java.io.File;
import java.util.Scanner;
import java.io.FileWriter;
public class Lab1 {
static int count = 0;
static int[] newData2 = new int[count];
// Method for reading the data and putting it into different arrays
static int[] readData() {
File f = new File("data.txt");
int[] newData = new int[100];
try {
Scanner s = new Scanner(f);
while (s.hasNext()) {
newData[count++] = s.nextInt();
}
for (int i = 0; i < newData2.length; i++) {
newData[i] = newData2[i];
return newData2;
}
} catch (Exception e) {
System.out.println("Could not read the file.");
}
}
static int min(int[] newData2) {
int min = newData2[0];
for (int i = 0; i < newData2.length; i++) {
if (newData2[i] < min) {
min = newData2[i];
}
}
return min;
}
static int max(int[] newData2) {
int max = newData2[0];
for (int i = 0; i < newData2.length; i++) {
if (newData2[i] > max) {
max = newData2[i];
}
}
return max;
}
static double average(int[] newData2) {
double average = 0;
int sum = 0;
for (int i = 0; i < newData2.length; i++) {
sum = newData2[i];
}
average = sum / newData2.length;
return average;
}
/*
* static int stddev(int[] newData2) { int[] avgDif = new
* int[newData2.length]; for(int i = 0; i < newData2.length; i++) {
* avgDif[i] = (int) (average(newData2) - newData2[i]); }
*
* }
*/
void write(String newdata, int min, int max, double average, int stddev) {
try {
File file = new File("stats.txt");
file.createNewFile();
FileWriter writer = new FileWriter("stats.txt");
writer.write("Minimum: " + min + "Maximum: " + max + "Average: " + average);
writer.close();
}catch(Exception e) {
System.out.println("Unable to write to the file.");
}
public static void main(String[] args) {
}
}
}
I have an error in my readData method, and it tells me that:
This method must return a result type of int[].
I'm literally returning an int array so I don't understand what the problem here is.
Then in my main method it says void is an invalid type for the variable main.
Here are some pointers:
each exit point of a method returning something must return something, if the line new Scanner(f); throws an exception, the first return is not reached, so you need a default one, like this:
private int[] readData() {
File f = new File("data.txt");
int count = 0;
int[] newData = new int[100];
try {
Scanner s = new Scanner(f);
while (s.hasNext()) {
newData[count++] = s.nextInt(); // maybe you should handle the case where your input is too large for the array "newData"
}
return Arrays.copyOf(newData, count);
} catch (Exception e) {
System.out.println("Could not read the file.");
}
return null;
}
To reduce the size of an array, you should use Arrays.copyOf (see below)
You should avoid static fields (and in your case none are required)
Your method min and max are assuming there are elements in the array (at least one), you should not do that (or test it with an if):
private int min(int[] data) {
int min = Integer.MAX_VALUE; // handy constant :)
for (int i = 0; i < data.length; i++) {
if (data[i] < min) {
min = data[i];
}
}
return min;
}
private int max(int[] data) {
int max = 0;
for (int i = 0; i < data.length; i++) {
if (data[i] > max) {
max = data[i];
}
}
return max;
}
In your average method there are a few mistakes:
private double average(int[] data) {
int sum = 0;
for (int i = 0; i < data.length; i++) {
sum += data[i]; // here if you want a sum it's += not =
}
return (1.0 * sum) / data.length; // you want a double division, local "average" was useless
}
arrays are iterables so you can use "new style" for loops:
for (int value : newData) {
// use value
}
Some reading:
Java Integer division: How do you produce a double?
“Missing return statement” within if / for / while
static int[] readData() {
File f = new File("data.txt");
int[] newData = new int[100];
try {
Scanner s = new Scanner(f);
while (s.hasNext()) {
newData[count++] = s.nextInt();
}
for (int i = 0; i < newData2.length; i++) {
newData[i] = newData2[i];
return newData2;
}
} catch (Exception e) {
System.out.println("Could not read the file.");
}
//TODO: return something here if there is some kind of error
}
Because of the try-catch block you need to account for every possibility that could occur. When you return the array when the program succeeds you are expecting a return, but when there is an exception the program still expects a return value, but you did not provide one.
We had to write a sorting algorithm ourselves. I wrote one, it works for 20-5000 data sets of integer, finishes in about 4 milliseconds. However, when I moved on to the 25000 data set, it stopped working at numbers with value 804; I have been trying to figure out why for the past 2 days and have no luck, my teacher tried his hand at it for 5 minutes and gave up. Any ideas as to why it would just get stuck on an infinite loop on the same number would be very much appreciated!
Edit: Commented inner loop
Edit 2: Added full code
Here is the code:
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.NoSuchElementException;
public class sort_old
{
static long steps=0;
static int nums, temp;
static int[] numbers, sorted, usedNum;
static String path="20_source.txt";
static Scanner scan;
static boolean used;
public static void main()
{
try
{
scan = new Scanner(new File(path));
while(scan.hasNextInt())
{
nums++;
scan.nextInt();
}
numbers= new int[nums];
sorted = new int[nums];
usedNum = new int[nums];
scan.close();
scan = new Scanner (new File(path));
try
{
for(int x = 0; x < nums; x++)
{
numbers[x]=scan.nextInt();
}
}
catch(NoSuchElementException e)
{
}
scan.close();
sortLargestToSmallest();
System.out.println(checkResults(sorted,true));
}
catch(FileNotFoundException e)
{
System.out.println("Sucks to suck");
}
}
private static void sortLargestToSmallest()
{
int counter=nums-1; // mums is the number of numbers in the data set.
for(int y = 0; y < nums; y ++)
{
temp = num[0]; //num[] is the array containing all the numbers
used=false; //boolean to for checking if the number was used already
for(int x = 0; x < nums; x ++)
{
if(temp<=num[x]) //finding the largest number
{
for(int j = 0; j < y; j++) //only check up to the numbers already assigned
{
if(usedNum[j]==x) //see if the number is already used. usedNum[] stores indexes of numbers already used; compare to current index
{
used=true; //the number is already sorted, so it moves on to the next
break;
}
else
used=false;
step++;
}
if(!used)//only if the number is not already sorted is it changed to temp
{
temp=num[x];
usedNum[y]=x;
}
}
}
sorted[counter]=temp; //putting the sorted value into the sorted array
counter--; // we were asked to sort from smallest to largest, but for some reason it didn't work.
}
}
}
public static boolean checkResults (int[] theArray, boolean report)
{
System.out.println("Checking Validity");
boolean stillValid = true;
int counter = 0;
while (stillValid && counter < theArray.length - 1)
{
if (theArray[counter] > theArray[counter + 1])
{
stillValid = false;
}
counter++;
}
if (report)
{
if (stillValid)
{
System.out.println("Checked " + theArray.length + " values. Sort is valid");
}
else
{
System.out.println("Checked " + theArray.length + " values. Found error at " + counter);
}
}
return stillValid;
}
}
I'm working on a project for a class, and I think I've got it mostly figured out, but it keeps giving me different Exception errors and now I'm stumped.
The instructions can be found here: http://www.cse.ohio-state.edu/cse1223/currentsem/projects/CSE1223Project11.html
Here is the code I have thus far, currently giving me and IndexOutOfBounds exception in the getMaximum method.
Any help would be much appreciated.
import java.io.*;
import java.util.*;
public class Project11a {
public static void main(String[] args) throws FileNotFoundException {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter an input file name: ");
String fileName = keyboard.nextLine();
Scanner in = new Scanner(new File(fileName));
System.out.print("Enter an output file name: ");
String outFile = keyboard.nextLine();
PrintWriter outputFile = new PrintWriter(outFile);
while (in.hasNextLine()) {
String name = in.nextLine();
List<Integer> series = readNextSeries(in);
int mean = getAverage(series);
int median = getMedian(series);
int max = getMaximum(series);
int min = getMinimum(series);
outputFile.printf("%-22s%6d%n", name, mean, median, max, min);
}
in.close();
outputFile.close();
}
// Given a Scanner as input read in a list of integers one at a time until a
// negative
// value is read from the Scanner. Store these integers in an
// ArrayList<Integer> and
// return the ArrayList<Integer> to the calling program.
private static List<Integer> readNextSeries(Scanner inScanner) {
List<Integer> nextSeries = new ArrayList<Integer>();
while (inScanner.hasNextInt()) {
int currentLine = inScanner.nextInt();
if (currentLine != -1) {
nextSeries.add(currentLine);
} else {
break;
}
}
return nextSeries;
}
// Given a List<Integer> of integers, compute the median of the list and
// return it to
// the calling program.
private static int getMedian(List<Integer> inList) {
Collections.sort(inList);
int middle = inList.size() / 2;
int median = -1;
if (inList.size() % 2 == 1) {
median = inList.get(middle);
} else {
try {
median = (inList.get(middle - 1) + inList.get(middle)) / 2;
} catch (Exception e) {
}
}
return median;
}
// Given a List<Integer> of integers, compute the average of the list and
// return it to
// the calling program.
private static int getAverage(List<Integer> inList) {
int average = 0;
if (inList.size() == 0) {
return 0;
}
for (int i = 0; i < inList.size(); i++) {
average += inList.get(i);
}
return (average / inList.size());
}
// Given a List<Integer> of integers, compute the maximum of the list and
// return it to
// the calling program.
private static int getMaximum(List<Integer> inList) {
int max = inList.get(0);
for (int i = 1; i < inList.size(); i++) {
if (inList.get(i) > max) {
max = inList.get(i);
}
}
return max;
}
// Given a List<Integer> of integers, compute the maximum of the list and
// return it to
// the calling program.
private static int getMinimum(List<Integer> inList) {
int min = inList.get(0);
for (int i = 1; i < inList.size(); i++) {
if (inList.get(i) < min) {
min = inList.get(i);
}
}
return min;
}
}
Seemed like that your list is empty.
What can triggered the exception is the statement:
int max = inList.get(0);
So your inList do not have the value in the first index,which means the inList is empty.
I am trying to implement an OutOfStockException for when the user attempts to buy more items than there are available. I'm not sure if my implementation is correct. Does this look OK to you?
public class OutOfStockException extends Exception {
public OutOfStockException(){
super();
}
public OutOfStockException(String s){
super(s);
}
}
This is the class where I need to test it:
import javax.swing.JOptionPane;
public class SwimItems {
static final int MAX = 100;
public static void main (String [] args)
{
Item [] items = new Item[MAX];
int numItems;
numItems = fillFreebies(items);
numItems += fillTaxable(items,numItems);
numItems += fillNonTaxable(items,numItems);
sellStuff(items, numItems);
}
private static int num(String which) {
int n = 0;
do {
try{
n=Integer.parseInt(JOptionPane.showInputDialog("Enter number of "+which+" items to add to stock:"));
}
catch(NumberFormatException nfe){
System.out.println("Number Format Exception in num method");
}
} while (n < 1 || n > MAX/3);
return n;
}
private static int fillFreebies(Item [] list)
{
int n = num("FREEBIES");
for (int i = 0; i < n; i++)
try{
list [i] = new Item(JOptionPane.showInputDialog("What freebie item will you give away?"),
Integer.parseInt(JOptionPane.showInputDialog("How many do you have?")));
}
catch(NumberFormatException nfe){
System.out.println("Number Format Exception in fillFreebies method");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("Array Index Out Of Bounds Exception in fillFreebies method");
}
return n;
}
private static int fillTaxable(Item [] list, int number)
{
int n = num("Taxable Items");
for (int i = number ; i < n + number; i++)
try{
list [i] = new TaxableItem(JOptionPane.showInputDialog("What taxable item will you sell?"),
Double.parseDouble(JOptionPane.showInputDialog("How much will you charge (not including tax) for each?")),
Integer.parseInt(JOptionPane.showInputDialog("How many do you have?")));
}
catch(NumberFormatException nfe){
System.out.println("Number Format Exception in fillTaxable method");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("Array Index Out Of Bounds Exception in fillTaxable method");
}
return n;
}
private static int fillNonTaxable(Item [] list, int number)
{
int n = num("Non-Taxable Items");
for (int i = number ; i < n + number; i++)
try{
list [i] = new SaleItem(JOptionPane.showInputDialog("What non-taxable item will you sell?"),
Double.parseDouble(JOptionPane.showInputDialog("How much will you charge for each?")),
Integer.parseInt(JOptionPane.showInputDialog("How many do you have?")));
}
catch(NumberFormatException nfe){
System.out.println("Number Format Exception in fillNonTaxable method");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("Array Index Out Of Bounds Exception in fillNonTaxable method");
}
return n;
}
private static String listEm(Item [] all, int n, boolean numInc)
{
String list = "Items: ";
for (int i = 0; i < n; i++)
{
try{
list += "\n"+ (i+1)+". "+all[i].toString() ;
if (all[i] instanceof SaleItem) list += " (taxable) ";
if (numInc) list += " (Number in Stock: "+all[i].getNum()+")";
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("Array Index Out Of Bounds Exception in listEm method");
}
catch(NullPointerException npe){
System.out.println("Null Pointer Exception in listEm method");
}
}
return list;
}
private static void sellStuff (Item [] list, int n) {
int choice;
do {
try{
choice = Integer.parseInt(JOptionPane.showInputDialog("Enter item of choice: "+listEm(list, n, false)));
}
catch(NumberFormatException nfe){
System.out.println("Number Format Exception in sellStuff method");
}
}while (JOptionPane.showConfirmDialog(null, "Another customer?")==JOptionPane.YES_OPTION);
JOptionPane.showMessageDialog(null, "Remaining "+listEm(list, n, true));
}
}
The implementation looks fine; you don't have to do much in an exception class. You might consider adding members for what the thing was that was out of stock, how many were requested, and how many there were in stock when the request was made so that code catching the exception has access to that information. So for instance, here I've a stock item code:
public class OutOfStockException extends Exception {
private int stockCode;
public OutOfStockException(int stockCode){
super();
this.stockCode = stockCode;
}
public OutOfStockException(String s){
super(s);
this.stockCode = stockCode;
}
public int getStockCode() {
return this.stockCode;
}
}
You could then create one like this:
throw new OutOfStockException(StockCodes.WIDGET, "Out of widgets");
But that's up to you, and at that point it's just class design like anything else.
Many times, with these sorts of things, I only include constructors with the individual parts, and then have the class itself generate the message for the underlying Exception getMessage message. So:
public class OutOfStockException extends Exception {
private int stockCode;
public OutOfStockException(int stockCode){
super("Out of " + StockCodes.getDescription(stockCode));
this.stockCode = stockCode;
}
public int getStockCode() {
return this.stockCode;
}
}
// Throwing one:
throw new OutOfStockException(StockCodes.WIDGETS);
But again it's just class design at that point.
All of that aside, and this is slightly off-topic, but being out of stock on an item seems to me to be a normal situation, not an exceptional one; are you sure an exception is really the right way to model it?
Yes, your exception is correctly implemented.
However, I'd suggest including more information in it:
the product in question
the attempted number of items to order
the actual number of remaining items
for example, if the product "Bike" has 2 remaining items, but one tries to order three, the exception would be constructed and thrown like
throw new OutOfStockException(product, requestedQuantity, actualQuantity)
Your exception looks ok.
I'm not sure about your SaleItem and TaxableItem classes though.
if (all[i] instanceof SaleItem) list += " (taxable) ";
is a code smell - having to check the instance of the class before doing something (and I'm not sure the names makes sense given the above). Why not override the appropriate methods on the class to do the above automatically for the appropriate subclass.
I disagree with the use of Exception here. You should only use one for exceptional conditions as the nomenclature suggests and not for control flow as this will make your code far more pleasant to read. Also exceptions do not get optimized byt the JVM and as such execute a lot slower.