How does the scope of this private method work? - java

My question is: how can I see the Tuple result in the process method if it was created in the check method? How am I able to use it there, if it was created in a private method?
public class Problem13 {
private Tuple<Integer> costs;
private Tuple<String> names;
private Tuple<Integer> result;
private int budget;
private int minDelta, minCost, totalCost;
public void process(String fileName) {
if (!read(fileName))
return;
if (budget >= totalCost) {
System.out.println("You can buy all items");
return;
}
if (budget < minCost) {
System.out.println("You cannot buy items");
return;
}
minDelta = -1;
int n = costs.getLength();
Set<Integer> interval = new IntegerInterval(0, n - 1);
for (int k = n - 1; k > 0; --k) {
Combinations<Integer> combinations = new Combinations<Integer>(interval, k);
combinations.produce((tuple) -> !check(tuple));
if (minDelta == 0)
break;
}
if (result == null)
System.out.println("No solution found");
else {
int k = result.getLength();
for (int j = 0; j < k; ++j)
System.out.printf("%s ", names.get(result.get(j)));
System.out.printf("(%d)\n", minDelta);
}
}
public static void main(String[] args) {
new Problem13().process("data/input13.txt");
}
private boolean check(Tuple<Integer> tuple) {
int k = tuple.getLength();
int currentCost = 0;
for (int i = 0; i < k; ++i) {
int j = tuple.get(i);
currentCost += costs.get(j);
if (currentCost > budget)
return false;
}
int d = budget - currentCost;
if (minDelta < 0 || d < minDelta) {
minDelta = d;
result = new ArrayTuple<>(k);
for (int i = 0; i < k; ++i)
result.set(i, tuple.get(i));
}
return minDelta == 0;
}

private means private to the class. So Problem13 can see anything defined in that class, whether private, public, protected or package private.
Also, the access modifier of the method only affects who can call it, not where the results can be seen. For instance, if result was defined as a public field, any class (not just Problem13) could see it.
You can find many good breakdowns of access modifiers out there on the Interwebs. Here's one.

Related

How do I avoid making methods and variables static in this code?

I was solving past exams for my java class and I'm struggling with one of them. I keep getting wrong result and I think its because all of classes and instance variables are static. How do I avoid making them static? Also this question basically wants you to find same letters of the location given in args[1] and convert them to the "S" if they are near of the given location (Args are "K,K,K,Y-K,Y,M,M-K,Y,Y,Y 2,1 S" if you need)
public class MatrixRefill {
public static String[][] matrix;
public static int rows;
public static int cols;
public static String enemy;
public static String target;
public static void main(String[] args) {
target = args[2];
rows = Integer.parseInt(args[1].substring(0,1));
cols = Integer.parseInt(args[1].substring(2));
matrix = matrixCreator(args[0]);
enemy = matrix[rows][cols];
recursive(rows, cols, target);
printer(matrix);
}
public static String[][] matrixCreator(String mx) {
int ro = 0;
int co = 0;
for (int i = 0; i < mx.length(); i++) {
if (mx.substring(i,i+1).equals(","))
co++;
if (mx.substring(i,i+1).equals("-"))
ro++;
}
String[][] matriks = new String[ro+1][co/3+1];
ro = 0;
co = 0;
for (int j = 0; j < mx.length(); j++) {
if (mx.substring(j,j+1).equals(","))
co++;
else if (mx.substring(j,j+1).equals("-")) {
ro++;
co = 0;
}
else
matriks[ro][co] = mx.substring(j,j+1);
}
return matriks;
}
public static void recursive(int row, int col, String target) {
if (valid(row,col)) {
recursive(row+1,col, target);
recursive(row,col+1, target);
recursive(row,col-1, target);
recursive(row-1,col, target);
matrix[row][col] = target;
}
}
public static boolean valid(int row, int col) {
boolean result = false;
if (row >= 0 && row < matrix.length && col >= 0 && col < matrix[row].length)
if (matrix[row][col] == enemy)
result = true;
return result;
}
public static void printer(String[][] owo) {
for(int i = 0; i < owo.length; i++) {
for(int j = 0; j < owo[i].length; j++) {
System.out.print(owo[i][j]);
if(j < owo[i].length - 1)
System.out.print(" ");
}
System.out.println();
}
}
}
Remove the static keyword from your methods and instance fields. But to call them from within main you need to create an instance of the containing class (in this case the one that contains the main method) and use that to call the other methods. What I do sometimes is to create an instance method (i.e. non-static) and call that to start the process. Then everything that would be in main I would put in that method. Here is an example.
public static void main(String[] args) {
MatrixRefill mr = new MatrixRefill();
mr.start();
}
public void start() {
target = args[2];
rows = Integer.parseInt(args[1].substring(0,1));
cols = Integer.parseInt(args[1].substring(2));
matrix = matrixCreator(args[0]);
enemy = matrix[rows][cols];
recursive(rows, cols, target);
printer(matrix);
}
// rest of code here
}
By putting what was in main in the start method you can call the other instance methods and access instance fields without qualifying them with a reference to the class (i.e. in this case prefixing with mr.)

Selection Sort not sorting Java

I am working on a selection sort in Java. It will prompt a user to enter in 10 names and then sort them alphabetically. It is sorting some of them but not completely and cannot figure out why it is sorting some values and not others. I believe I have implemented the sort and swap correctly but I feel as though I am missing something. Any help is appreciated as always.
import java.util.*;
public class sortingProgram {
static String studentName[] = new String[10];
static int i;
static Scanner scnr = new Scanner(System.in);
public static void enterNames() {
for (i = 0; i < studentName.length; i++) {
System.out.println("Please enter a student name: ");
studentName[i] = scnr.nextLine();
}
}
public static void sortNames(String sortArray[]) {
int smallindex;
for (int i = 0; i < sortArray.length; i++) {
smallindex = i;
for (int j = i + 1; j < sortArray.length; j++) {
if (sortArray[j].compareTo(sortArray[smallindex]) < 0) {
smallindex = j;
if (smallindex != i)
swap(sortArray, smallindex, i);
}
}
}
System.out.println(Arrays.toString(sortArray));
}
public static void swap(Object a[], int i1, int j1) {
Object temp = a[i1];
a[i1] = a[j1];
a[j1] = temp;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
enterNames();
sortNames(studentName);
}
}
You are doing your swap too early. You need to wait until the smallest has been determined before swapping. You are swapping whenever you detect a smaller one.
public static void sortNames(String sortArray[]) {
for (int i = 0; i < sortArray.length; i++) {
int smallindex = i;
for (int j = i + 1; j < sortArray.length; j++) {
if (sortArray[j].compareTo(sortArray[smallindex]) < 0) {
smallindex = j;
// Move this.
//if (smallindex != i)
// swap(sortArray, smallindex, i);
}
}
// To here.
if (smallindex != i)
swap(sortArray, smallindex, i);
}
}
public static void swap(Object a[], int i1, int j1) {
Object temp = a[i1];
a[i1] = a[j1];
a[j1] = temp;
}
private void test() {
String[] names = {"C", "B", "A", "9"};
System.out.println(Arrays.toString(names));
sortNames(names);
System.out.println(Arrays.toString(names));
}
use below changes in your program.
import java.util.*;
public class SortingProgram {
static String studentName[] = new String[10];
static int i;
static Scanner scnr = new Scanner(System.in);
public static void enterNames() {
for (i = 0; i < studentName.length; i++) {
System.out.println("Please enter a student name: ");
studentName[i] = scnr.nextLine();
}
}
public static void sortNames(String sortArray[]) {
int smallindex;
for (int i = 0; i < sortArray.length; i++) {
smallindex = i;
for (int j = i + 1; j < sortArray.length; j++) {
if (sortArray[j].compareTo(sortArray[smallindex]) < 0) {
smallindex = j;
//if (smallindex != i) No need here
//swap(sortArray, smallindex, i);
}
}
//place your swaping code here
if (smallindex != i)
swap(sortArray, smallindex, i);
}
System.out.println(Arrays.toString(sortArray));
}
public static void swap(Object a[], int i1, int j1) {
Object temp = a[i1];
a[i1] = a[j1];
a[j1] = temp;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
enterNames();
sortNames(studentName);
}
}
after making these changes your program works. your code not works properly because you perform swap early.

== null Doesn't work java

I have made a function for objects to reserve seats in a area. But if 2 objects enter the function at the same time they get the same seats. How do I solve this?
The Function getFreeChairs, returns the chair positions. And sets the Fan. But if two fans enter it at the same time they both get the same seats.
Sven
package model;
import actors.Fan;
import java.util.ArrayList;
import java.util.List;
/**
* Created by sveno on 12-10-2016.
*/
public class Vak {
private static int autoId = 1;
private String naam;
private int rijen, stoelenperrij, id;
private List<ArrayList> rows = new ArrayList<>();
private Fan fan = null;
public Vak(String naam, int rijen, int stoelenperrij) {
this.naam = naam;
this.rijen = rijen;
this.stoelenperrij = stoelenperrij;
this.id = autoId;
autoId++;
for (int i = 0; i < rijen; i++) {
rows.add(new ArrayList<Fan>());
}
for (ArrayList row : rows) {
for (int j = 0; j < stoelenperrij; j++) {
row.add(fan);
}
}
}
public void removeReserved(int rij, List<Integer> stoelen){
for (int i = 0; i < stoelen.size()-1; i++) {
//De reserveer alle stoelen
ArrayList<Fan> stoel = rows.get(rij);
stoel.set(stoelen.get(i),fan);
}
}
public int getRijen() {
return rijen;
}
public int getStoelenperrij() {
return stoelenperrij;
}
public List<ArrayList> getRows() {
return rows;
}
public int[] getFreeChairs(int aantalStoelen, Fan fan){
//Check for free seats
int count = 1;
int[] stoelenleeg = new int[aantalStoelen+1];
for (int j = 0; j < rows.size(); j++) {
for (int k = 0; k < rows.get(j).size(); k++) {
if (rows.get(j).get(k) == null){
stoelenleeg[count-1] = k;
count++;
//Not enough seats next to each other
if(count==aantalStoelen+1){
stoelenleeg[aantalStoelen] = j+1;
for (int o = 0; o < stoelenleeg.length-1; o++) {
ArrayList<Fan> stoel = rows.get(j);
stoel.set(stoelenleeg[o],fan);
}
return stoelenleeg;
}
}else{
//Not enough seats
stoelenleeg = new int[aantalStoelen+1];
count=1;
}
}
}
return stoelenleeg;
}
}
If your code is used in a concurrent context (multiple threads), you need to make sure that your code is thread safe.
It means that, only one single thread(person) should be able to call the getFreeChairs function(reserve a seat at a time)
The easy way to do it in java is to use the synchronized key word in the method definition:
public synchronized int[] getFreeChairs(int aantalStoelen, Fan fan){
...
}

My function seems to be editing multiple objects

In my Sudoku Android application I have a solve function that solves a Sudoku puzzle (a CellField object). However for some reason when I clone a CellField object and I call the solve method on the cloned object, the solve method solves both of the CellField objects but I only want it to solve the cloned CellField object and not the original object. Any suggestions? Thanks
Here I clone the CellField object (the clone is called temp) and also call the solve method
CellField temp = null;
try {
temp = board.cf.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
int x = randInt(0,8);
int y = randInt(0,8);
while (!temp.getCell(y,x).isEditable && board.cf.getCell(y,x).getValue() == 0) {
x = randInt(0,8);
y = randInt(0,8);
}
SudokuSolver solver = new SudokuSolver();
solver.solve(temp);
Here is my solve method and SudokuSolver class
package com.example.czhou.myapplication2;
import java.util.*;
public class SudokuSolver {
static boolean retry;
public static int randInt(ArrayList<Integer> candidates) {
int min = 0;
int max = candidates.size() - 1;
//inclusive
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
int result = candidates.get(randomNum);
candidates.remove(randomNum);
return result;
}
public boolean solve(CellField field) {
// write your code here
boolean isValid = true;
Set<Integer> toRemove = new HashSet<>();
int i;
int j;
for (int k = 0; k < 9; k++) {
for (int l = 0; l < 9; l++) {
field.getCell(k, l).restAlt();
if (field.getCell(k, l).alt.indexOf(field.getCell(k, l).getValue()) != -1) {
field.getCell(k, l).alt.remove(field.getCell(k, l).alt.indexOf(field.getCell(k, l).getValue()));
}
}
}
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
if (field.getCell(i,j).getValue() == 0 && field.getCell(i,j).alt.size() == 0){
field.getCell(i,j).restAlt();
}
if (field.getCell(i, j).isEditable) {
toRemove.clear();
for (int k = 0; k < 9; k++) {
toRemove.add(field.getCell(k, j).getValue());
}
toRemove.addAll(field.getSectorCandidates(i, j));
for (int k = 0; k < 9; k++) {
toRemove.add(field.getCell(i, k).getValue());
}
toRemove.removeAll(Collections.singleton(0));
field.getCell(i, j).alt.removeAll(toRemove);
if (toRemove.size() == 9 || field.getCell(i, j).alt.size() == 0) {
//When there no candidates are available
//in the current cell, come here
//toRemove.clear();
Cell cell;
boolean stop = false;
backtrack:
for (int k = j; !stop; k--) {
if (k == -1) {
if (i != 0) {
--i;
} else {
break;
}
k = 8;
}
j = k;
// Scan for previous cells have alternative candidates
cell = field.getCell(i, k);
if (cell.alt.size() > 0 && cell.isEditable) {
//bookmark the original cell
//int nextCell = k+1;
// If found a cell set value as first alternative
cell.setValue(cell.alt.get(0));
break backtrack;
} else if (cell.isEditable){
// if no alternatives set cell to 0 and continue backwards
cell.setValue(0);
}
}
} else {
field.getCell(i, j).setValue(randInt(field.getCell(i, j).alt));
}
}
}
}
// for (int m = 0; m < 9; m++) {
// for (int l = 0; l < 9; l++) {
// if (l == 0) {
// System.out.println();
// }
// System.out.print(field.getCell(m, l).getValue());
// }
// }
// System.out.println();
// System.out.println("================");
return isValid;
}
}
Here is my CellField class
package com.example.czhou.myapplication2;
import android.util.Log;
import java.io.Serializable;
import java.util.*;
import java.util.regex.Matcher;
public class CellField implements Cloneable{
protected Cell[][] field = new Cell[9][9];
public CharSequence timeElapsed = "00:00";
public CellField() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
field[i][j] = new Cell();
}
}
}
public CellField(CellField another) {
List<Cell[]> cellfield = Arrays.asList(another.field);
this.field = (Cell[][]) cellfield.toArray();
}
public CellField clone() throws CloneNotSupportedException {
return (CellField)super.clone();
}
}
The problem is with you Clone method, as #ρяσѕρєя said, you should do a deep copy. Because right now you are returning the same reference. Try something like this:
public CellField clone() throws CloneNotSupportedException {
CellField clone = new CellField();
clone.field = this.field;
clone.timeElapsed = this.timeElapsed;
return clone;
}
It is a matter of shallow copy versus deep copy.
class SomeClass implements Cloneable {
// This is the problematic field. It doesn't get cloned the way you think it is.
public Integer[] field = new Integer[5];
public SomeClass clone() throws CloneNotSupportedException {
return (SomeClass) super.clone();
}
}
public class HelloWorld {
public static void main(String []args){
SomeClass first = new SomeClass();
SomeClass second = null;
try {
second = first.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(first.field);
System.out.println(second.field);
// Their addresses in memory are the same
// Modifying one would modify the other
// first.field == second.field -> true
}
}
In the above example, I cloned one instance of the class into another and, yet, they share the same field. Mutating fields of the first instance of the class will directly affect the field in the second instance of the class since they both own a reference to it.
Instead of using Cloneable, you could define a copy constructor and perform the cloning on your own.
More advanced details can be found on How to properly override clone method?

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

Categories