Java implementing Exception Handling - java

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.

Related

Exception in thread "main" java.util.InputMismatchException errors

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.
}

Creating java program assistance

I have to create a java program with two classes and the challenge is =
"Enter in 10 numbers. Calculate the average and display all numbers greater than the average."
I am fairly new to java and I have no idea on what I am doing and how to send array values from one class to another.
import BreezySwing.KeyboardReader;
import javax.swing.*;
public class Average {
public static void main(String[] args) {
KeyboardReader reader = new KeyboardReader();
System.out.print('\u000C');
AverageTest at = new AverageTest();
int numberArray[];
int i;
numberArray = new int[10];
for (i = 0; i < 10; i++) {
numberArray[i] = reader.readInt("Enter a number: ");
at.setnumber(numberArray);
}
}
}
import javax.swing.*;
import BreezySwing.*;
public class AverageTest
{
private int number[];
private int a;
public void setnumber(int number)
{
number = numberArray;
}
}
import java.util.Scanner;
public class AverageTest {
public static void main(String[] args) {
int[] array = new int[10];
// Try with resources, automatically closes the reader once the work is done
// Read 10 integers from the standard input
try (Scanner reader = new Scanner(System.in);) {
for (int i = 0; i < 2; i++) {
System.out.println("Enter a number: ");
array[i] = reader.nextInt();
}
} catch (Exception e) {
e.printStackTrace();
}
// we have an array with 10 numbers, now create an average object by passing
// this array to the Average class constructor
Average averageObj = new Average(array);
// Compute the average
float average = averageObj.average();
System.out.println("Average: " + average);
System.out.println("Numbers greater than average: ");
// Print out the numbers which are greater than or equal to the average
for (int i = 0; i < array.length; i++) {
if (array[i] >= average) {
System.out.println(array[i]);
}
}
}
}
class Average {
private int[] array;
public Average(int[] array) {
if (array == null || array.length == 0) {
throw new IllegalArgumentException("Array cannot be null or empty");
}
this.array = array;
}
public int[] getArray() {
return array;
}
/**
* Computes the average of the given array and returns it.
*/
public float average() {
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
return (float) sum/array.length;
}
}
there are 3 steps about this issue:
1.Enter in 10 numbers.
2.Calculate the average.
3.display all numbers greater than the average.
you have done the step 1,that's great.
and I can see that you are trying to do the step 2.
here's the suggestion of your issue:
if you want to send array values from A class to B,you just need to invoke the method of B in the A correctly.
I think I know what you are trying to do.
the problem of your code that you can't send array values from one class to another is because the method's parameter type is not matching.
the method public void setnumber(int number),the parameter is an int type,and you try to refer it to an int array,this's wrong.
first, you need to change the method's definition to public void setnumber(int[] numberarray),and try to figure out why we have to write like this.
then finish the step 2.
Hope it'll help.

Java sorting text file with Comparable

I need a program that reads in data and sorts the file in descending order using quicksort based on the index provided for instance this is the data using comparable
adviser,32/60,125,256,6000,256,16,128,198,199
amdahl,470v/7,29,8000,32000,32,8,32,269,253
amdahl,470v/7a,29,8000,32000,32,8,32,220,253
amdahl,470v/7b,29,8000,32000,32,8,32,172,253
amdahl,470v/7c,29,8000,16000,32,8,16,132,132
And i need to sort by the 5th index(mmax) case 2 and the 6th(cache) case 3 and the ninth index(php) case 4 in descending order & print the first index which is already sorted case 1
The problems with my code are as follows:
It doesn't sort based off the index
It gives me an error at runtime with the code: Arrays.sort(c);
Please help with suggestions
Thanks
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Prog4 {
static Scanner input;
static File filename;
/**
* This function displays the menu for the user to choose an option from
*/
public void menu() {
System.out.println("Option 1: Sort by VENDOR: ");
System.out.println("Option 2: Sort decreasing number by MMAX: ");
System.out.println("Option 3: Sort decreasing number by CACH: ");
System.out.println("Option 4: Sort decreasing number by PRP: ");
System.out.println("Option 5: Quit program");
}
/**
* Constructor to handle the cases in the menu options
* #throws FileNotFoundException
* #throws IOException
*/
public Prog4() throws FileNotFoundException {
//Accepts user input
Scanner in = new Scanner(System.in);
//calls the menu method
menu();
//Initializes the run variable making the program loop until the user terminates the program
Boolean run = true;
//While loop
while (run) {
switch (in.nextInt()) {
case 1:
System.out.println("Option 1 selected");
System.out.println("Sorted by vendor:");
filename = new File("machine.txt");
//Instantiate Scanner s with f variable within parameters
//surround with try and catch to see whether the file was read or not
try {
input = new Scanner(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Instantiate a new Array of String type
String array [] = new String[10];
//while it has next ..
while (input.hasNext()) {
//Initialize variable
int i = 0;
//store each word read in array and use variable to move across array array[i] = input.next();
//print
System.out.println(array[i]);
//so we increment so we can store in the next array index
i++;
}
case 2:
System.out.println("Press any key to continue");
Scanner input2 = new Scanner(System.in);
String x = input2.nextLine();
if (x.equals(0)) continue;
System.out.println("Option 2 selected") ;
Computer[] c = new Computer[10];
filename = new File("machine.txt");
try {
input = new Scanner(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Arrays.sort(c);
while (input.hasNextLine()) {
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
}
}
}
/**
* Main method
* #param args
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
//Calls the constructor
new Prog4();
//static Scanner input;
}
public static void quickSort(int arr[], int left, int right) {
if (left < right) {
int q = partition(arr, left, right);
quickSort(arr, left, q);
quickSort(arr, q+1, right);
}
}
private static int partition(int arr[], int left, int right) {
int x = arr[left];
int i = left - 1;
int j = right + 1;
while (true) {
i++;
while (i < right && arr[i] < x)
i++;
j--;
while (j > left && arr[j] > x)
j--;
if (i < j)
swap(arr, i, j);
else
return j;
}
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Comparator class:
import java.util.Comparator;
class Computer implements Comparable<Computer> {
private String vendor;
private int mmax;
private int cach;
private int php;
public Computer(int value) {
this.mmax = value;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public int getMmax() {
return mmax;
}
public void setMmax(int mmax) {
this.mmax = mmax;
}
public int getCach() {
return cach;
}
public void setCach(int cach) {
this.cach = cach;
}
public int getPhp() {
return php;
}
public void setPhp(int php){
this.php = php;
}
#Override
public int compareTo(Computer m) {
if (mmax < m.mmax) {
return -1;
}
if (mmax > m.mmax) {
return 1;
}
// only sort by height if age is equal
if (cach > m.cach) {
return -1;
}
if (cach < m.cach) {
return 1;
}
if (php > m.php) {
return -1;
}
if (php < m.php) {
return 1;
}
return 0;
}
public static Comparator<Computer> ComparemMax = new Comparator<Computer>() {
#Override
public int compare(Computer p1, Computer p2) {
return p2.getMmax() - p1.getMmax();
}
};
}
The biggest problem is that the Computer classes do not get instantiated for each line that gets read.
As you want to have different sort options depending on the user input, you can not let the Computer class determine the compare method, but instead you will need to create a separate Comparator implementation for each sort option. Next, make the file read operation generic and abstract it away in a separate method call from each selected case. Instead of an array of Computers, I would make it a List or a Set, because you don't (want to) know the length up front.
I would like to lay out the steps in detail so that you could figure out each step for yourself. You have got a lot of it right.. but there are gaps.
Create a Computer class. It should have a constructor which takes a single String and splits it using the separator ',' and parses each part to String/int as applicable. (It would be preferable for you to parse and store the whole string.. which means you can have 10 fields in your class)
Create a blank ArrayList to store the Computer objects.
Iterate through the file and readLine
Call the Computer constructor using the String representing each line in the file within the while loop
Add the new Computer object to the computers ArrayList
Write 5 different comparators.
Based on user input, instantiate the correct comparator and pass it to the sort method
Print the sorted array
If you still face a problem, mention the specific point at which you like more clarity..

Algorithm course: Output of int sort and method to sort Strings

My assignment asks me to make a TV show program, where I can input shows, delete, modify and sort them. What I'm stuck on is the sorting part. With the show, it asks for the name, day a new episode premieres, and time. Those are the keys I need to sort it by.
The program prompts the user to input one of those keys, then the program needs to sort (sorting by day will sort alphabetically).
I made a class and used an array. Here is the class:
public class showInfo
{
String name;
String day;
int time;
}
And the method to sort by time in the code:
public static void intSort()
{
int min;
for (int i = 0; i < arr.length; i++)
{
// Assume first element is min
min = i;
for (int j = i+1; j < arr.length; j++)
{
if (arr[j].time < arr[min].time)
{
min = j;
}
}
if (min != i)
{
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < arr.length; i++)
{
System.out.println(arr[i].name + " - " + arr[i].day + " - " + arr[i].time + " hours");
}
}
When I call it and output it in the main, it only shows "TV Shows by Time" and not the list. Why is this?
Also, I need to make ONE method that I will be able to use to sort both the day AND the name (both Strings). How can I do this without using those specific arrays (arr[i].name, arr[i].day) in the method?
Any help would be greatly appreciated! Thanks in advance!
In this part of your code
if (min != i) {
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
You're just changing the time when you should move the whole object instead. To fix it, the code must behave like this:
if (min != i) {
//saving the object reference from arr[i] in a temp variable
showInfo temp = arr[i];
//swapping the elements
arr[i] = arr[min];
arr[min] = temp;
}
I̶t̶ ̶w̶o̶u̶l̶d̶ ̶b̶e̶ ̶b̶e̶t̶t̶e̶r̶ ̶t̶o̶ ̶u̶s̶e̶ ̶ Arrays#sort ̶w̶h̶e̶r̶e̶ ̶y̶o̶u̶ ̶p̶r̶o̶v̶i̶d̶e̶ ̶a̶ ̶c̶u̶s̶t̶o̶m̶ ̶̶C̶o̶m̶p̶a̶r̶a̶t̶o̶r̶̶ ̶o̶f̶ ̶t̶h̶e̶ ̶c̶l̶a̶s̶s̶ ̶b̶e̶i̶n̶g̶ ̶s̶o̶r̶t̶e̶d̶ ̶(̶i̶f̶ ̶y̶o̶u̶ ̶a̶r̶e̶ ̶a̶l̶l̶o̶w̶e̶d̶ ̶t̶o̶ ̶u̶s̶e̶ ̶t̶h̶i̶s̶ ̶a̶p̶p̶r̶o̶a̶c̶h̶)̶.̶ ̶S̶h̶o̶r̶t̶ ̶e̶x̶a̶m̶p̶l̶e̶:̶
showInfo[] showInfoArray = ...
//your array declared and filled with data
//sorting the array
Arrays.sort(showInfoArray, new Comparator<showInfo>() {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
//basic implementation
if (showInfo1.getTime() == showInfo2.getTime()) {
return showInfo1.getName().compareTo(showInfo2.getName());
}
return Integer.compare(showInfo1.getTime(), showInfo2.getTime());
}
});
//showInfoArray will be sorted...
Since you have to use a custom made sorting algorithm and support different ways to sort the data, then you just have to change the way you compare your data. This mean, in your current code, change this part
if (arr[j].time < arr[min].time) {
min = j;
}
To something more generic like
if (compare(arr[j], arr[min]) < 0) {
min = j;
}
Where you only need to change the implementation of the compare method by the one you need. Still, it will be too complex to create and maintain a method that can support different ways to compare the data. So the best option seems to be a Comparator<showInfo>, making your code look like this:
if (showInfoComparator.compare(arr[j], arr[min]) < 0) {
min = j;
}
where the showInfoComparator holds the logic to compare the elements. Now your intSort would become into something more generic:
public static void genericSort(Comparator<showInfo> showInfoComparator) {
//your current implementation with few modifications
//...
//using the comparator to find the minimum element
if (showInfoComparator.compare(arr[j], arr[min]) < 0) {
min = j;
}
//...
//swapping the elements directly in the array instead of swapping part of the data
if (min != i) {
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
//...
}
Now, you just have to write a set of Comparator<showInfo> implementations that supports your custom criteria. For example, here's one that compares showInfo instances using the time field:
public class ShowInfoTimeComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
return Integer.compare(showInfo1.getTime(), showInfo2.getTime());
}
}
Another comparator that uses the name field:
public class ShowInfoNameComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
return showInfo1.getName().compareTo(showInfo2.getName());
}
}
Now in your code you can call it like this1:
if (*compare by time*) {
genericSort(showInfoArray, new ShowInfoTimeComparator());
}
if (*compare by name*) {
genericSort(showInfoArray, new ShowInfoNameComparator());
}
if (*another custom rule*) {
genericSort(showInfoArray, new ShowInfoAnotherCustomRuleComparator());
}
where now you can implement a custom rule like compare showInfo objects using two or more fields. Taking as example your name and day fields (as stated in the question):
public class ShowInfoNameAndDayComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
int nameComparisonResult = showInfo1.getName().compareTo(showInfo2.getName());
if (nameComparisonResult == 0) {
return showInfo1.getDay().compareTo(showInfo2.getDay());
}
return nameComparisonResult;
}
}
1: There are other ways to solve this instead using lot of if statements, but looks like that's outside the question scope. If not, edit the question and add it to show another ways to solve this.
Other tips for your current code:
Declare the names of the classes using CamelCase, where the first letter of the class name is Upper Case, so your showInfo class must be renamed to ShowInfo.
To access to the fields of a class, use proper getters and setters instead of marking the fields as public or leaving the with default scope. This mean, your ShowInfo class should become into:
public class ShowInfo {
private String name;
private String day;
private int time;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//similar for other fields in the class
}
Use selection sort algorithm which is easy to implement,
for (int i = 0; i < arr.length; i++)
{
for (int j = i + 1; j < arr.length; j++)
{
if (arr[i].time > arr[j].time) // Here ur code that which should be compare
{
ShowInfo temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
no need to check min element. go through this wiki http://en.wikipedia.org/wiki/Selection_sort
Why not you use a Collection for this sort of a thingy to work. Moreover, in your added example, you are simply changing one attribute of a given object, while sorting, though you not changing the position of the object as a whole, inside the given list.
Create a List which will contain the references of all the Shows, now compare each attribute of one Show with another, in the List. Once the algorithm feels like, that swapping needs to be done, simply pick the reference from the List, save it in a temp variable, replace it with a new reference at this location, and set duplicate to the one stored in the temp variable. You are done, List is sorted :-)
Here is one small example for the same, for help :
import java.io.*;
import java.util.*;
public class Sorter {
private BufferedReader input;
private List<ShowInfo> showList;
public Sorter() {
showList = new ArrayList<ShowInfo>();
input = new BufferedReader(
new InputStreamReader((System.in)));
}
private void createList() throws IOException {
for (int i = 0; i < 5; i++) {
System.out.format("Enter Show Name :");
String name = input.readLine();
System.out.format("Enter Time of the Show : ");
int time = Integer.parseInt(input.readLine());
ShowInfo show = new ShowInfo(name, time);
showList.add(show);
}
}
private void performTask() {
try {
createList();
} catch (Exception e) {
e.printStackTrace();
}
sortByTime(showList);
}
private void sortByTime(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
if (showList.get(j).getTime() <
showList.get(min).getTime()) {
min = j;
}
}
if (min != i) {
ShowInfo temp = showList.get(i);
showList.set(i, showList.get(min));
showList.set(min, temp);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
public static void main(String[] args) {
new Sorter().performTask();
}
}
class ShowInfo {
private String name;
int time;
public ShowInfo(String n, int t) {
name = n;
time = t;
}
public String getName() {
return name;
}
public int getTime() {
return time;
}
}
EDIT 2 :
For sorting By Name you can use this function :
private void sortByName(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
int value = (showList.get(j).getName()).compareToIgnoreCase(
showList.get(min).getName());
if (value < 0)
min = j;
}
if (min != i) {
ShowInfo temp = showList.get(i);
showList.set(i, showList.get(min));
showList.set(min, temp);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
EDIT 3 :
Added Comparable<?> Interface, to the existing class to perform sorting based on specified input. Though one can improve on the logic, by using Enumeration, though leaving it for the OP to try his/her hands on :-)
import java.io.*;
import java.util.*;
public class Sorter {
private BufferedReader input;
private List<ShowInfo> showList;
private int command;
public Sorter() {
showList = new ArrayList<ShowInfo>();
input = new BufferedReader(
new InputStreamReader((System.in)));
command = -1;
}
private void createList() throws IOException {
for (int i = 0; i < 5; i++) {
System.out.format("Enter Show Name :");
String name = input.readLine();
System.out.format("Enter Time of the Show : ");
int time = Integer.parseInt(input.readLine());
ShowInfo show = new ShowInfo(name, time);
showList.add(show);
}
}
private void performTask() {
try {
createList();
} catch (Exception e) {
e.printStackTrace();
}
System.out.format("How would you like to sort : %n");
System.out.format("Press 0 : By Name%n");
System.out.format("Press 1 : By Time%n");
try {
command = Integer.parseInt(input.readLine());
} catch (Exception e) {
e.printStackTrace();
}
sortList(showList);
}
private void sortList(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
showList.get(j).setValues(command);
int value = showList.get(j).compareTo(showList.get(min));
if (value < 0) {
min = j;
}
}
if (min != i) {
Collections.swap(showList, i, min);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
public static void main(String[] args) {
new Sorter().performTask();
}
}
class ShowInfo implements Comparable<ShowInfo> {
private String name;
private int time;
private int command;
public ShowInfo(String n, int t) {
name = n;
time = t;
}
public String getName() {
return name;
}
public int getTime() {
return time;
}
public void setValues(int cmd) {
command = cmd;
}
public int compareTo(ShowInfo show) {
int lastCmp = 1;
if (command == 0) {
lastCmp = name.compareTo(show.name);
} else if (command == 1) {
if (time < show.time) {
lastCmp = -1;
} else if (time == show.time) {
lastCmp = 0;
} else if (time > show.time) {
lastCmp = 1;
}
}
return lastCmp;
}
}

How to turn static methods into non-static. Small explanation/examples related to java oop

I cant get how to use/create oop code without word static. I read Sun tutorials, have book and examples. I know there are constructors, then "pointer" this etc. I can create some easy non-static methods with return statement. The real problem is, I just don't understand how it works.I hope some communication gives me kick to move on. If someone asks, this is not homework. I just want to learn how to code.
The following code are static methods and some very basic algorithms. I'd like to know how to change it to non-static code with logical steps(please.)
The second code shows some non-static code I can write but not fully understand nor use it as template to rewrite the first code.
Thanks in advance for any hints.
import java.util.Scanner;
/**
*
* #author
*/
public class NumberArray2{
public static int[] table() {
Scanner Scan = new Scanner(System.in);
System.out.println("How many numbers?");
int s = Scan.nextInt();
int[] tab = new int[s];
System.out.println("Write a numbers: ");
for(int i=0; i<tab.length; i++){
tab[i] = Scan.nextInt();
}
System.out.println("");
return tab;
}
static public void output(int [] tab){
for(int i=0; i<tab.length; i++){
if(tab[i] != 0)
System.out.println(tab[i]);
}
}
static public void max(int [] tab){
int maxNum = 0;
for(int i=0; i<tab.length; i++){
if(tab[i] > maxNum)
maxNum = tab[i];
}
//return maxNum;
System.out.println(maxNum);
}
static public void divide(int [] tab){
for(int i=0; i<tab.length; i++){
if((tab[i] % 3 == 0) && tab[i] != 0)
System.out.println(tab[i]);
}
}
static public void average(int [] tab){
int sum = 0;
for(int i=0; i<tab.length; i++)
sum = sum + tab[i];
int avervalue = sum/tab.length;
System.out.println(avervalue);
}
public static void isPrime(int[] tab) {
for (int i = 0; i < tab.length; i++) {
if (isPrimeNum(tab[i])) {
System.out.println(tab[i]);
}
}
}
public static boolean isPrimeNum(int n) {
boolean prime = true;
for (long i = 3; i <= Math.sqrt(n); i += 2) {
if (n % i == 0) {
prime = false;
break;
}
}
if ((n % 2 != 0 && prime && n > 2) || n == 2) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
int[] inputTable = table();
//int s = table();
System.out.println("Written numbers:");
output(inputTable);
System.out.println("Largest number: ");
max(inputTable);
System.out.println("All numbers that can be divided by three: ");
divide(inputTable);
System.out.println("Average value: ");
average(inputTable);
System.out.println("Prime numbers: ");
isPrime(inputTable);
}
}
Second code
public class Complex {
// datové složky
public double re;
public double im;
// konstruktory
public Complex() {
}
public Complex(double r) {
this(r, 0.0);
}
public Complex(double r, double i) {
re = r;
im = i;
}
public double abs() {
return Math.sqrt(re * re + im * im);
}
public Complex plus(Complex c) {
return new Complex(re + c.re, im + c.im);
}
public Complex minus(Complex c) {
return new Complex(re - c.re, im - c.im);
}
public String toString() {
return "[" + re + ", " + im + "]";
}
}
Let's start with a simple example:
public class Main
{
public static void main(final String[] argv)
{
final Person personA;
final Person personB;
personA = new Person("John", "Doe");
personB = new Person("Jane", "Doe");
System.out.println(personA.getFullName());
System.out.println(personB.getFullName());
}
}
class Person
{
private final String firstName;
private final String lastName;
public Person(final String fName,
final String lName)
{
firstName = fName;
lastName = lName;
}
public String getFullName()
{
return (lastName + ", " + firstName);
}
}
I am going to make a minor change to the getFullName method now:
public String getFullName()
{
return (this.lastName + ", " + this.firstName);
}
Notice the "this." that I now use.
The question is where did "this" come from? It is not declared as a variable anywhere - so it is like magic. It turns out that "this" is a hidden parameter to each instance method (an instance method is a method that is not static). You can essentially think that the compiler takes your code and re-writes it like this (in reality this is not what happens - but I wanted the code to compile):
public class Main
{
public static void main(final String[] argv)
{
final Person personA;
final Person personB;
personA = new Person("John", "Doe");
personB = new Person("Jane", "Doe");
System.out.println(Person.getFullName(personA));
System.out.println(Person.getFullName(personB));
}
}
class Person
{
private final String firstName;
private final String lastName;
public Person(final String fName,
final String lName)
{
firstName = fName;
lastName = lName;
}
public static String getFullName(final Person thisx)
{
return (thisx.lastName + ", " + thisx.firstName);
}
}
So when you are looking at the code remember that instance methods have a hidden parameter that tells it which actual object the variables belong to.
Hopefully this gets you going in the right direction, if so have a stab at re-writing the first class using objects - if you get stuck post what you tried, if you get all the way done post it and I am sure we help you see if you got it right.
First, OOP is based around objects. They should represent (abstract) real-world objects/concepts. The common example being:
Car
properties - engine, gearbox, chasis
methods - ignite, run, brake
The ignite method depends on the engine field.
Static methods are those that do not depend on object state. I.e. they are not associated with the notion of objects. Single-program algorithms, mathematical calculations, and such are preferably static. Why? Because they take an input and produce output, without the need to represent anything in the process, as objects. Furthermore, this saves unnecessary object instantiations.
Take a look at java.lang.Math - it's methods are static for that precise reason.
The program below has been coded by making the methods non-static.
import java.util.Scanner;
public class NumberArray2{
private int tab[]; // Now table becomes an instance variable.
// allocation and initilization of the table now happens in the constructor.
public NumberArray2() {
Scanner Scan = new Scanner(System.in);
System.out.println("How many numbers?");
int s = Scan.nextInt();
tab = new int[s];
System.out.println("Write a numbers: ");
for(int i=0; i<tab.length; i++){
tab[i] = Scan.nextInt();
}
System.out.println("");
}
public void output(){
for(int i=0; i<tab.length; i++){
if(tab[i] != 0)
System.out.println(tab[i]);
}
}
public void max(){
int maxNum = 0;
for(int i=0; i<tab.length; i++){
if(tab[i] > maxNum)
maxNum = tab[i];
}
System.out.println(maxNum);
}
public void divide(){
for(int i=0; i<tab.length; i++){
if((tab[i] % 3 == 0) && tab[i] != 0)
System.out.println(tab[i]);
}
}
public void average(){
int sum = 0;
for(int i=0; i<tab.length; i++)
sum = sum + tab[i];
int avervalue = sum/tab.length;
System.out.println(avervalue);
}
public void isPrime() {
for (int i = 0; i < tab.length; i++) {
if (isPrimeNum(tab[i])) {
System.out.println(tab[i]);
}
}
}
public boolean isPrimeNum(int n) {
boolean prime = true;
for (long i = 3; i <= Math.sqrt(n); i += 2) {
if (n % i == 0) {
prime = false;
break;
}
}
if ((n % 2 != 0 && prime && n > 2) || n == 2) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
// instatiate the class.
NumberArray2 obj = new NumberArray2();
System.out.println("Written numbers:");
obj.output(); // call the methods on the object..no need to pass table anymore.
System.out.println("Largest number: ");
obj.max();
System.out.println("All numbers that can be divided by three: ");
obj.divide();
System.out.println("Average value: ");
obj.average();
System.out.println("Prime numbers: ");
obj.isPrime();
}
}
Changes made:
int tab[] has now been made an
instance variable.
allocation and initialization of the
table happens in the constructor.
Since this must happen for every
instantiated object, it is better to
keep this in a constructor.
The methods need not be called with
table as an argument as all methods
have full access to the instance
variable(table in this case)
The methods have now been made
non-static, so they cannot be called
using the class name, instead we need
to instantiate the class to create an
object and then call the methods on
that object using the obj.method()
syntax.
It is easy to transform class methods from beeing static to non-static. All you have to do is remove "static" from all method names. (Ofc dont do it in public static void main as you would be unable to run the example)
Example:
public static boolean isPrimeNum(int n) { would become
public boolean isPrimeNum(int n) {
In public static void main where you call the methods you would have to chang your calls from beeing static, to refere to an object of the specified class.
Before:
NumberArray2.isPrimeNum(11);
After:
NumberArray2 numberarray2 = new NumberArray2(); // Create object of given class
numberarray2.isPrimeNum(11); // Call a method of the given object
In NumberArray2 you havent included an constructor (the constructor is like a contractor. He takes the blueprint (class file, NumberArray2) and follows the guidelines to make for example a building (object).
When you deside to not include a constructor the java compilator will add on for you. It would look like this:
public NumberArray2(){};
Hope this helps. And you are right, this looks like homework :D
I belive its common practice to supply the public modifier first. You haven done this in "your" first method, but in the others you have static public. Atleast for readability you should do both (code will compile ether way, as the compilator dosnt care).
The code is clean and easy to read. This is hard to do for someone who is "just want to learn how to code". Hope this helps you on your way with your "justlookslikehomeworkbutisnt" learning.
I'm guessing you're confused of what "static" does. In OOP everything is an object. Every object has its own functions/variables. e.g.
Person john = new Person("John",18);
Person alice = new Person("Alice",17);
if the function to set the 'name' variable would be non static i.e. string setName(string name){} this means that the object john has a name "John" and the object alice has a name "Alice"
static is used when you want to retain a value of something across all objects of the same class.
class Person{
static int amountOfPeopleCreated;
public Person(string name, int age){
amountOfPeopleCreated++;
setName(name);
setAge(age);
}
...
}
so if you'd the value of amountOfPeopleCreated will be the same no matter if you check alice or john.

Categories