Returning Elements From ArrayList Alphabetically - java

I'm working on a program to manipulate chemical formulae, and I'm writing a method which needs to loop through an ArrayList called "terms" and return the first one alphabetically.
e.g. terms = {Term('H',4),Term('C',2),Term('H',4),Term('C',1)} would return Term('C',2)
I've written this code so far but it's not working. I'm a real beginner to the Java language.
public Term nextElement()
{
int i = 0;
for (i = 0; i < terms.size()-1; i++)
{
int j = 1;
while (i + j <= terms.size())
if (terms.get(i).getElement() > terms.get(i+j).getElement())
{
terms.remove(i+j++);
return terms.get(i);
}
}
return null;
}
I'd appreciate any ideas or suggestions to solve this problem. Thanks!

You have two options here:
Let your Term class implement Comparable interface and override its compareTo() method. Then you can use Collections.sort(listOfTerms) to sort them and loop through.
Add class TermComparator which implements Comparator interface, use Collections.sort(listOfTerms, new TermComparator()) and loops through the sorted list.

1- you can implement Comparable and override compareTo()
int compareTo(Object obj){
Term term = (Term)obj;
if(term.getElement < this.getElement())
return 1;
else if (term.getElement == this.getElement())
return 0;
else
return -1;
}
then use
Collection.sort(terms);
2-
public Term nextElement()
{
char minElement = 'Z';
int index = 0;
for (int i = 0; i < terms.size(); i++)
{
if (terms.get(i).getElement() < minElement)
{
minElement = terms.get(i).getElement();
index = i;
}
}
Term temp = terms.get(index);
terms.remove(index)
return temp;
}

use Collections.sort(terms);it will arrange the list alphabetically.

This is what you need to do:
List<Term> terms = //your list
Collections.sort(terms, new Comparator<Term>() {
#Override
public int compare(Term t1, Term t2) {
return t1.getElement().compareTo(t2.getElement());
}
});

CODE:
public class CodeSample {
public static void main(String[] args) {
List<Term> terms=new ArrayList<Term>();
terms.add(new Term('H',4));
terms.add(new Term('C',2));
terms.add(new Term('H',4));
terms.add(new Term('C',1));
System.out.println("Before Sorting");
for(Term term:terms){
System.out.print(term.toString().concat(" "));
}
Collections.sort(terms,new Comparator<Term>() {
#Override
public int compare(Term object1, Term object2) {
if (object1.getElement() != object2.getElement()) {
return object1.getElement() - object2.getElement();
} else {
return object2.getCount() - object1.getCount();
}
}
});
//Sorted terms
System.out.println("After Sorting");
for(Term term:terms){
System.out.print(term.toString().concat(" "));
}
}
public static class Term{
private char element;
private int count;
public Term(char element, int count) {
super();
this.element = element;
this.count = count;
}
public char getElement() {
return element;
}
public int getCount() {
return count;
}
#Override
public String toString() {
return "Term [element=" + element + ", count=" + count + "]";
}
}
}
OUTPUT:
Before Sorting
Term [element=H, count=4] Term [element=C, count=2] Term [element=H, count=4] Term [element=C, count=1]
After Sorting
Term [element=C, count=2] Term [element=C, count=1] Term [element=H, count=4] Term [element=H, count=4]

Related

Generic Linear List based on Arrays

I'm trying to write a Linear List based on arrays, but make the list be able to store any value by using Java Generics. This way I can create other programs that utilize it, but pass in different data types. I'm not entirely sure how to do this, any help would be appreciated.
I guess Im struggling trying to set it up and create the functions. The generic type really messes me up.
For example, trying to add a removeFirst() function, I cant use a loop like this:
for (int i = 0; i < n - 1; i++)
newList[i] = newList[i + 1];
— as it says The type of the expression must be an array type but it resolved to ArrayList.
Fair warning, I'm still learning data structures. This is what I have so far:
import java.util.ArrayList;
public class LinearList<T> {
private static int SIZE = 10;
private int n = 0;
private final ArrayList<T> newList = new ArrayList<T>(SIZE);
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
public void add(T value, int position) {
newList.add(position, value);
n++;
}
public void addFirst(T value) {
newList.add(0, value);
n++;
}
public void removeLast() {
T value = null;
for (int i = 0; i < newList.size(); i++)
value = newList.get(i);
newList.remove(value);
n--;
}
public void removeFirst() {
newList.remove(0);
n--;
}
public T first() {
return newList.get(0);
}
public T last() {
int value = 0;
for (int i = 0; i < newList.size() - 1; i++)
value++;
return newList.get(value);
}
public int count() {
return n;
}
public boolean isFull() {
return (n >= SIZE);
}
public boolean isEmpty() {
return (n <= 0);
}
//part 4
public void Grow() {
int grow = SIZE / 2;
SIZE = SIZE + grow;
}
public void Shrink() {
int grow = SIZE / 2;
SIZE = SIZE - grow;
}
public String toString() {
String outStr = "" + newList;
return outStr;
}
}
A good start would be to make it non-generic with a class you are comfortable with, such as an Integer.
Once you have it set up, you can then make it generic by adding <T> to the class name, then replacing all references of Integer with T.
public class MyArray{ becomes public class MyArray<T>{
public Integer add(Integer value){ becomes public T add(T value){
See What are Generics in Java? for more help

Set an element in an arraylist of a specific class

In my program I have a pair class:
class Pair {
public int ind = 0;
public String letter = "";
public Pair(int a, String b) {
ind = a; //index
letter = b;
}
}
how do I set the index (ind) of an element in an arraylist of Pairs? I have tried
RightMotor.ind.set(j, i);
and
LeftMotor.set(j, i).ind;
but they don't seem to work.
First you need to 'get' the Pair instance, like:
Pair pair = LeftMotor.get(i);
then you can change its fields:
pair.ind = j;
This can also be done in one line:
LeftMotor.get(i).ind = j;
Hint 1: this is not changing the index (position) of the instance in the list, LeftMotor.get(i) will still return the same element. i and ind are two completely disjunct values.
Hint 2: normally it is better to have private fields and have a method (setter) to change the fields (encapsulation):
class Pair {
private int ind = 0;
private String letter = "";
public Pair(int a, String b) {
ind = a; //index
letter = b;
}
public void setInd(int newInd) {
ind = newInd;
}
}
Hint 3: just to be clear, just because it is called ind it is not the index (position) of the list. It is a whole different question if you want to change the order of the elements in the list.
You want to make those instance variables private, then getters/setters to access/modify them. This allows you to safely and securely manipulate the data with a reduced chance of bleedover (which can crash your program or cause unintended consequences).
Within your class:
class Pair {
private int ind = 0;
private String letter = "";
public Pair(int index, String letter) {
ind = index;
letter = letter;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getLetter() {
return this.letter;
}
public void setLetter(String letter) {
this.letter = letter;
}
public void setIndexAndLetter(int index, String letter) {
this.index = index;
this.letter = letter;
}
}
Elsewhere in your program:
Pair rightMotor = new Pair(1, "a");
Pair leftMotor = new Pair(2, "b");
Pair middleMotor = new Pair(0, "");
rightMotor.setInd(3);
leftMotor.setLetter("d");
middleMotor.setIndAndLetter(rightMotor.getInd() + leftMotor.getInd(), "z");
You have to create a Pair instance using the Pair constructor before adding it to the ArrayList:
RightMotor.add(new Pair(i,j)); // assuming i is an int and j is a String
If you want to replace the Pair stored in a given index use:
RightMotor.set(index,new Pair(i,j));
If you want to change an existing Pair stored in the ArrayList:
RightMotor.get(index).setInd(newValue);
This will require a setter method in your Pair class:
public void setInd (int i) {
ind = i;
}
So I think that you could solve this in a couple of different ways... however I think I know what you are trying to do.... I feel like you are trying to keep the ArrayList and the Pair index synchronized... either way you will need a helper method to accomplish this. I agree with hendripd that you should use private variables and utilize the getters and setters. However this is my solution.
Pair:
public class Pair implements Comparable<Pair> {
private int index = 0;
private String letter = "";
public Pair(int index, String letter) {
this.index = index;
this.letter = letter;
}
public Pair(Pair pair) {
this.index = pair.getIndex();
this.letter = pair.getLetter();
}
#Override
public int compareTo(Pair pair) {
if (this.index > pair.index) {
return 1;
} else if (this.index < pair.index) {
return -1;
} else {
return 0;
}
}
#Override
public String toString() {
return this.index + " " + this.letter;
}
public int getIndex() {
return this.index;
}
public String getLetter() {
return this.letter;
}
public void setIndex(int index) {
this.index = index;
}
public void setLetter(String letter) {
this.letter = letter;
}
}
Main:
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static ArrayList<Pair> rightMotor;
public static void main(String[] args) {
rightMotor = new ArrayList<Pair>();
rightMotor.add(new Pair(0, "a"));
rightMotor.add(new Pair(1, "b"));
setIndex(rightMotor, 0, 1);
// If you choose to go with the second option utilizing Comparable<Pair>
// Collections.sort(rightMotor);
for (Pair pair : rightMotor) {
System.out.println(pair.toString());
}
}
public static void setIndex(ArrayList<Pair> motor, int oldIndex, int newIndex) {
Pair tempPair = new Pair(motor.get(oldIndex));
if (oldIndex < newIndex) {
for (int i = oldIndex; i < newIndex; i++) {
motor.set(i, motor.get(i + 1));
motor.get(i).setIndex(i);
}
} else if (oldIndex > newIndex) {
for (int i = oldIndex; i > newIndex; i--) {
motor.set(i, motor.get(i - 1));
motor.get(i).setIndex(i);
}
}
tempPair.setIndex(newIndex);
motor.set(newIndex, tempPair);
}
}
Note that the Pair class implements comparable... you could use Collections.Sort(rightMotor) which then you would only need to fix the indexes of the instances... i.e.
public static void setIndex(ArrayList<Pair> motor, int oldIndex, int newIndex) {
motor.get(oldIndex).setIndex(newIndex);
if (oldIndex < newIndex) {
for (int i = oldIndex; i < newIndex; i++) {
motor.get(i + 1).setIndex(i);
}
} else if (oldIndex > newIndex) {
for (int i = oldIndex; i > newIndex; i--) {
motor.get(i - 1).setIndex(i);
}
}
}
Or... you can use the original one I posted which also handles the sorting at the same time. This keeps your Arraylist in numerical order by index either way.
Test casing:
rightMotor.add(new Pair(0, "a"));
rightMotor.add(new Pair(1, "b"));
rightMotor.add(new Pair(2, "c"));
rightMotor.add(new Pair(3, "d"));
rightMotor.add(new Pair(4, "e"));
rightMotor.add(new Pair(5, "f"));
setIndex(rightMotor, 0, 1);
setIndex(rightMotor, 3, 1);
setIndex(rightMotor, 4, 3);
outputs this result:
0 b
1 d
2 a
3 e
4 c
5 f

Return element at position index. (No ArrayList)

format: get(index):Object.
public class MyArrayList {
public String[] arrays = {};
public MyArrayList() {
arrays = new String[10];
}
public int get(int i){
for(int index = 0; index< arrays.length; index++) {
}
return i;
}
}
public class MyArrayListTest {
static MyArrayList zoo = new MyArrayList();
public static void printZoo() {
System.out.print("The zoo now holds " + zoo.size() + " animals: ");
for (int j = 0; j < zoo.size(); j++) System.out.print(zoo.get(j) + " ");
System.out.println();
}
public static void main(String[] args) {
System.out.println("Testing constructor, add(object) and size() ");
zoo.add("Ant");
zoo.add("Bison");
zoo.add("Camel");
zoo.add("Dog");
zoo.add("Elephant");
zoo.add("Frog");
zoo.add("Giraffe");
zoo.add("Horse");
printZoo();
System.out.println();
}
}
With this code it prints out:
Testing constructor, add(object) and size()
The zoo now holds 10 animals: 0 1 2 3 4 5 6 7 8 9
Obviously my code for get method is very wrong but instead of printing out the numbers it should print out "Ant","Bison,"Camel" etc.
All help appreciated for code as I'm a very new programmer. Thanks.
Fixing your Get Method
public int get(int i){
for(int index = 0; index< arrays.length; index++) {
}
return i;
}
Okay, so let's look at this shall we? There's a few values that the user can provide..
i < 0
0 < i < size of array <-- The only valid one.
i > size of array
So first you need to check for that!
if(i > 0 && i < arrays.length) {
// This is a valid index!
}
Okay, so you know it's a valid index. Step two is retrieving the value..
return arrays[i];
And finally, the return type needs to be set. At the moment it is int. It needs to be String in this example..
public String get(int i)
It's that simple! When you call printZoo(), you'll see the values and not their indices.
Onto your Objects
You can have an array of type Object without importing any classes. This will change arrays of type String[] to..
Object[] arrays;
Your Code is technically correct, but if you want to return string values in run time, you must change the value returned in method get to String as in
public int get(int i){
for(int index = 0; index< arrays.length; index++) {
}
return i;
to
public String get(int i){
return arrays[i];
}
Also in your method printZoo(), you have another loop, so i'd imagine your code printing out duplicate values. so why don't you have the printZoo Method dealing with the for loop and the get() method above displaying the values
So Change your get method to the one i have here, and everything should work for you
If it doesn't Work, then try these pieces of Code
MyArrayList.java
public class MyArrayList{
public String[] arrays = {};
public int i = 0;
public MyArrayList() {
arrays = new String[10];
}
public void add(String a)throws ListFullException{ //Add to List if Arraylist is not full
if(i != arrays.length-1){
arrays[i] = a;
i++;
}
else{
throw new ListFullException("List Full");
}
}
public String get(int i){
return arrays[i];
}
public int getArraySize(){
return arrays.length;
}
}
MyArrayListTest.java
public class MyArrayListTest {
static MyArrayList zoo = new MyArrayList();
public static void printZoo() {
System.out.print("The zoo now holds " + zoo.getArraySize() + " animals: ");
for (int j = 0; j < zoo.getArraySize(); j++) System.out.print(zoo.get(j) + " ");
System.out.println();
}
public static void main(String[] args) {
System.out.println("Testing constructor, add(object) and size() ");
zoo.add("Ant");
zoo.add("Bison");
zoo.add("Camel");
zoo.add("Dog");
zoo.add("Elephant");
zoo.add("Frog");
zoo.add("Giraffe");
zoo.add("Horse");
printZoo();
System.out.println();
}
}
And the Exceptions class
ListFullException.java
public class ListFullException extends RuntimeException{
public ListFullException(String m){
super(m);
}
}
I hope this will be a great study tool for you, if you feel this has helped you, upvote and accept :) :P
It is printing an int because you are calling zoo.get(j) and get() returns ints:
public int get(int i){
for(int index = 0; index< arrays.length; index++) {
}
return i;
You need to return a String, something along the lines of:
public String get(int i){
return arrays[i];
}

InventoryItem.java uses unchecked or unsafe operations

I'm learning about comparable and am implementing it in my Inventory class. However when I go to compile the code, the compiler gives an error.
InventoryItem.java uses unchecked or unsafe operations.
Can anyone please help me out. What is wrong with my code and what can I do to fix this issue. Thank you for your help in advance.
class InventoryItem implements Comparable<InventoryItem>
{
private String name;
private int uniqueItemID;
public InventoryItem()
{
name = " ";
uniqueItemID = 0;
}
public InventoryItem(String newName, int newItemID)
{
name = newName;
uniqueItemID = newItemID;
}
public InventoryItem(InventoryItem i)
{
name = i.name;
uniqueItemID = i.uniqueItemID;
}
public void setName(String newName)
{
name = newName;
}
public void setItemID(int newItemID)
{
uniqueItemID = newItemID;
}
public int getItemID()
{
return uniqueItemID;
}
public String getName()
{
return name;
}
public int compareTo(InventoryItem i)
{
int anotherUniqueID = i.getItemID();
return (this.uniqueItemID - anotherUniqueID);
}
public static void sort(Comparable[] a, int numberUsed)
{
int index, indexOfNextSmallest;
for(index = 0; index < numberUsed - 1; index++)
{
indexOfNextSmallest = indexOfSmallest(index, a, numberUsed);
interchange(index, indexOfNextSmallest, a);
}
}
private static int indexOfSmallest(int startIndex, Comparable[] a, int numberUsed)
{
Comparable min = a[startIndex];
int indexOfMin = startIndex;
int index;
for(index = startIndex + 1; index < numberUsed; index++)
{
if(a[index].compareTo(min) < 0)
{
min = a[index];
indexOfMin = index;
}
}
return indexOfMin;
}
private static void interchange(int i, int j, Comparable[] a)
{
Comparable temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
public class InventoryItemTester
{
public static void main(String [] args)
{
InventoryItem[] items = new InventoryItem[3];
items[0] = new InventoryItem("Pens", 2);
items[1] = new InventoryItem("Pencils", 3);
items[2] = new InventoryItem("Notebooks", 1);
System.out.println("Before sorting");
System.out.println(items[0]);
System.out.println(items[1]);
System.out.println(items[2]);
InventoryItem.sort(items, items.length);
System.out.println("After sorting");
System.out.println(items[0]);
System.out.println(items[1]);
System.out.println(items[2]);
}
}
At a guess I'd say this line is causing the issue (Your compiler tells you exactly which line is the problem, this might be useful to include in your next question):
private static int indexOfSmallest(int startIndex, Comparable[] a, int numberUsed)
{
Comparable min = a[startIndex];
int indexOfMin = startIndex;
int index;
for(index = startIndex + 1; index < numberUsed; index++)
{
here==========> if(a[index].compareTo(min) < 0)
{
You are calling compareTo with a InventoryItem where it is expecting an Object. You could add a #SuppressWarnings annotation which would make it go away :)
The basic idea of Comparable and Comparator is they apply a sorting order to an Object so that the standard JDK Collections objects can do all the hard work for you.
In your case your comparesTo method does the correct thing, however I'm not sure if this is good planning or good luck, so things to note:
InventoryItem.comparesTo method needs to evaluate the current instance to the provided instance and return an integer signifying the ordering, -1 means the instance (ie this) should be ordered before the argument, 0 means they are the same and 1 means the instance is after the argument. Something like this lets the JDK do all the hard work for you
public int compareTo(InventoryItem i)
{
return Integer.valueOf(this.uniqueItemID).compareTo(i.uniqueItemID);
}
In order to use Comparable all you really need to do is implement it and then use the standard JDK Collections classes to do all the heavy lifting for you, eg:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class InventoryItemTest
{
public static void main(String [] args)
{
List<InventoryItem> items = new ArrayList<InventoryItem>();
items.add(new InventoryItem("Pens", 2));
items.add(new InventoryItem("Pencils", 3));
items.add(new InventoryItem("Notebooks", 1));
System.out.println("Before sorting");
System.out.println(items);
Collections.sort(items);
System.out.println("After sorting");
System.out.println(items);
}
}
I realise this might not be as much fun as writing your own sorting algorithms but if you want to do that with no compiler warnings then you need to start looking at generics

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