For my assignment, I have to create both a method to sort integers and Strings stored in an object class. Keep in mind, I HAD TO USE CASTS. I wanted to use generics, but my teacher INSISTS on me using 1.4.2 (which don't have generics). I can sort time, and for the alphabetical sort, I used my method to sort time and added a compareTo. I played with it a bit, but when I output it, it gives me everything I inputted in the order I inputted it. Not in alphabetical.
Here's the class I created to store input:
public class showInfo
{
String name;
String day;
int time;
}
The following is the method to sort by name!
//method to sort and display info
public static void sortName(){
for(int i = 0; i < show.size() - 1; i++) {
for(int j = 0; j < show.size() - 1; j++){
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(i+1)).name) > 0){
showInfo temp = new showInfo();
temp.name = ((showInfo)show.get(j)).name;
temp.day = ((showInfo)show.get(j)).day;
temp.time = ((showInfo)show.get(j)).time;
((showInfo)show.get(j)).time = ((showInfo)show.get(i)).time;
((showInfo)show.get(j)).day = ((showInfo)show.get(i)).day;
((showInfo)show.get(j)).name = ((showInfo)show.get(i)).name;
((showInfo)show.get(i)).time = temp.time;
((showInfo)show.get(i)).day = temp.day;
((showInfo)show.get(i)).name = temp.name;
}
}
}
Any help would be great! Thanks in advance. :)
(PS. I'm aware I need to change "showInfo" to "ShowInfo", but I'll do it when I'm finished.)
One problem with your code is that you are comparing show.get(i) with show.get(i+1) but then swapping show.get(i) with show.get(j). You should be comparing to show.get(j). Also, the inner loop should go to j < show.size() rather than show.size() - 1. Finally, you can start the inner loop at i + 1 instead of at 0.
Once you determine that you need to swap, you can do much better by simply swapping references in the list, rather than swapping each field:
showInfo tmp = (showInfo)show.get(i);
show.set(i, show.get(j));
show.set(j, tmp);
I assume show is a List and you have to sort by name.
First, make showInfo implement Comparable:
public class showInfo implements Comparable
{
String name;
String day;
int time;
public int compareTo(Object o)
{
showInfo other = (showInfo) o;
return name.compareTo(other.name);
}
}
Then, use `Collections.sort()' on the list:
Collections.sort(show);
You can do something like this....
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class myComparator implements Comparator {
public int compare(Object o1, Object o2) {
return ((o1.toString().charAt(0) > o2.toString().charAt(0)) ? 1 : (o1
.toString().charAt(0) == o2.toString().charAt(0)) ? 0 : -1);
}
}
public class Sample {
/**
* #param args
*/
public static void main(String[] args) {
List l = new ArrayList();
l.add("hello");
l.add("abc");
l.add("World");
l.add("hi");
System.out.println("Before sorting");
for (Object i : l) {
System.out.println(i.toString());
}
Collections.sort(l, new myComparator());
System.out.println("After sorting");
for (Object i : l) {
System.out.println(i.toString());
}
}
}
You are incorrectly using i here :
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(i+1)).name) > 0){
I believe the second i should be j to achieve bubble sort
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(j+1)).name) > 0){
Not sure if this is what you look for, it uses casting insteads of generics, anyway, i hope this will help
pastebin
Related
There is a list of 200 students names and exam results.
My task is: "Create a constructor method for this list and put them in descending order with for statement".
I've done the first part. I can print out the list also. But I have no idea how to put them in descending order using for statement. Can anyone show me how to do that?
Current code:
package training;
public class ExamResult {
String studentName;
String examName;
int points;
String date;
ExamResult(String studentName, String examName, String date,int points) {
this.studentName=studentName;
this.examName=examName;
this.points=points;
this.date=date;
}
public void display() {
System.out.println(studentName + " " + examName + " " + date + " " + points);
}
}
package training;
public class DisplayExamResults {
public static void main (String args[]) {
ExamResult one=new ExamResult("Ryan Pena","Sociology","21/06/2016",16);
ExamResult two=new ExamResult("Portia Hamilton","Sociology","21/06/2016",34);
ExamResult three=new ExamResult("Ryan Pena","Sociology","21/06/2016",35);
one.display();
two.display();
three.display();
}
}
So, Daniel! This is going to be long because you are new to Java and I will try to explain everything. You can always read more about a lot of things here but I will explain just enough for this problem.
When you want to sort objects of a class, in your case, class ExamResult, you cannot just use a for loop on one of the fields and finish sorting. In order to achieve your desired sorting, you will need to use an interface called Comparable. This interface lets you write your own sorting criteria based on the structure of your class.
We will proceed step by step.
Step 1: Implement the Comparable interface in the ExamResult class
Since you want to sort objects of the ExamResult class, this is where you will implement the interface. By that, we mean, you will write how you want to sort your objects. We want to sort based on the student names. And for sorting, we will need to compare objects to see which one is greater than the other.
Here, we will use a term called overriding which basically means that we will override the comparison function which was declared in the Comparable interface.
Our definition below takes as input an object of the class ExamResult and compares its student name with that of the current object - this. On comparison, it returns an integer:
0, if the names are equal
>0, if the other object's student name is greater than the current one
<0, if the other object's student name is lesser than the current one
package training;
public class ExamResult implements Comparable<ExamResult> {
/* your previous code remains here as is*/
// this function returns the name of the student
public String getStudentName() { return studentName; }
#Override
// write your sorting criteria
public int compareTo(ExamResult other) {
String name1 = this.getStudentName();
String name2 = other.getStudentName();
return name1.compareTo(name2);
}
}
Step 2: Construct a list of ExamResult objects in DisplayExamResults class
Now that we have finished defining how to compare objects, we need a list of those objects on which we will run the for loop and perform the comparison.
We can do that in the DisplayExamResults class like so:
// Create a list of results on which you will run your for loop
List<ExamResult> resultList = new ArrayList<>();
resultList.add(one);
resultList.add(two);
resultList.add(three);
Here, the List interface lets you define a list of objects of any user defined class like yours. So you create a list and add the ExamResult objects to it.
Step 3: Sort using the for loop
This is the final step, where you perform the actual sorting in the DisplayExamResults class. We will first sort in ascending order and then reverse the list.
You start with a left (i) and a right (j) pointer. i is set to 0 because it starts at the beginning of the list and j is set at the end of the list.
As you keep comparing, if the object on the left is smaller than the one on the right, you just move on, i.e. increment i. Similarly, if the object on the right is greater than that on the left, just move on by decrementing j.
But, if the order is not like that, then you swap them. Which is what we do in the if statement. You can see that we are using the compareTo() function that we had defined above.
// Loop over that list to sort the objects
for (int i = 0; i < resultList.size(); i++) {
for (int j = resultList.size() - 1; j > i; j--) {
if (resultList.get(i).compareTo(resultList.get(j)) > 0) {
ExamResult temp = resultList.get(i);
resultList.set(i, resultList.get(j));
resultList.set(j, temp);
}
}
}
// For descending order
Collections.reverse(resultList);
// Display the results after sorting is over
for (ExamResult r : resultList) {
r.display();
}
Phew! Now, we put all that code together to get the following two files.
package training;
public class ExamResult implements Comparable<ExamResult> {
String studentName;
String examName;
int points;
String date;
ExamResult(String studentName, String examName, String date,int points) {
this.studentName=studentName;
this.examName=examName;
this.points=points;
this.date=date;
}
public void display() {
System.out.println(studentName + " " + examName + " " + date + " " + points);
}
// this function returns the name of the student
public String getStudentName() { return studentName; }
#Override
// write your sorting criteria
public int compareTo(ExamResult other) {
String name1 = this.getStudentName();
String name2 = other.getStudentName();
return name1.compareTo(name2);
}
}
And
package training;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DisplayExamResults {
public static void main (String args[]) {
ExamResult one = new ExamResult("Ryan Pena","Sociology","21/06/2016",16);
ExamResult two = new ExamResult("Portia Hamilton","Sociology","21/06/2016",34);
ExamResult three = new ExamResult("Ryan Pena","Sociology","21/06/2016",35);
one.display();
two.display();
three.display();
System.out.println("\n");
// Create a list of results on which you will run your for loop
List<ExamResult> resultList = new ArrayList<>();
resultList.add(one);
resultList.add(two);
resultList.add(three);
// Loop over that list to sort the objects
for (int i = 0; i < resultList.size(); i++) {
for (int j = resultList.size() - 1; j > i; j--) {
if (resultList.get(i).compareTo(resultList.get(j)) > 0) {
ExamResult temp = resultList.get(i);
resultList.set(i, resultList.get(j));
resultList.set(j, temp);
}
}
}
// For descending order
Collections.reverse(resultList);
// Display the results after sorting is over
for (ExamResult r : resultList) {
r.display();
}
}
}
I tried to explain the bits in there. Please read more and understand better. Hope it helps.
If the names are as a String Array or a List:
Using standard Java libraries:
String[] students = {"Aaron", "Jonas", "Bob", "Karl"};
Arrays.sort(students);
List<String> temp = new ArrayList<>(Arrays.asList(students));
Collections.reverse(temp);
temp.toArray(students);
OR
Using Bubblesort and chars to compare the strings:
String[] students = {"Aaron", "Jonas", "Bob", "Karl"};
char[] temp1;
char[] temp2;
int length;
for(int i = 0; i < students.length; i++){
temp1 = students[i].toLowerCase().toCharArray();
for(int n = i+1; n < students.length; n++){
temp2 = students[n].toLowerCase().toCharArray();
if(temp1.length > temp2.length)
length = temp2.length;
else
length = temp1.length;
for(int c = 0; c < length; c++){
if(temp1[c] < temp2[c]){
String temp = students[i];
students[i] = students[n];
students[n] = temp;
temp1 = students[i].toLowerCase().toCharArray();
break;
}
else if(temp1[c] > temp2[c])
break;
}
}
}
so I'm trying to write a method which uses generics. The method is suppose to takes a arrayList and return the highest value in the array. Here is the code to do that
public T largest() {
T value = myList.get(0);
for (int i = 1; i < myList.size(); i++) {
if (myList.get(i).doubleValue() > value.doubleValue()) {
value = myList.get(i);
}
}
return value;
}
Only problem is I'm not suppose to use .doubleValue. I've been stuck trying to figure it out for hours with no luck, Generics are reallyyyyy throwing me off for some reason. Am I suppose to somehow cast something? How can I write that above method without using .doubleValue()? Thanks!
I think this is what they had in mind when giving you this task.
The elements of your list need to be something that is Comparable.
This way you can compare them simply by calling compareTo.
This implementation is more general, more generic.
That is you don't need to limit yourself to using doubleValue in particular.
package test;
import java.util.Arrays;
import java.util.List;
public class Test001 {
public static void main(String[] args) {
Long a = largest(Arrays.asList(new Long[]{2L, 5L, 7L}));
Integer b = largest(Arrays.asList(new Integer[]{2, 5, 7}));
System.out.println(a);
System.out.println(b);
}
public static <T extends Comparable<? super T>> T largest(List<T> myList) {
T value = myList.get(0);
for (int i = 1; i < myList.size(); i++) {
if (myList.get(i).compareTo(value) > 0) {
value = myList.get(i);
}
}
return value;
}
}
You can only find the largest element if an ordering of the elements is defined. Since you're got giving a Comparator to the method to specify such an order, you're assuming "natural order", which means the elements must be Comparable.
Your function changes to the following (changed to static to make this standalone answer "complete"):
public static <T extends Comparable<T>> T largest(Iterable<T> myList) {
T largest = null;
for (T value : myList)
if (largest == null || value.compareTo(largest) > 0)
largest = value;
return largest;
}
This question already has answers here:
Sort ArrayList of custom Objects by property
(29 answers)
Closed 7 years ago.
I have a function which reads a CSV file and after some processing put the data into an
ArrayList<ArrayList<String>>.
So I have this:
ArrayList = list of rows
sub-ArrayList<String> = list of columns
Now I have to do this (I'm guessing the java way of doing this is to
use a Comparator): I need to sort these rows according to the string values of each field.
So, for example, if I have the rows (where each field is the final String in the ArrayList<ArrayList<String>> structure):
Name|Birthdate|FathersName
John,2001-01-01,Steven
John,2001-01-01,Albert
the sorting action should reverse these two rows (because the first 2
fields are equal so the third field determines the order).
Any tips on how to do this would be greatly appreciated.
Answer: Arnaud Denoyelle's answer led me to the following generic solution
private Comparator<List<String>> comparator = new Comparator<List<String>>() {
#Override
public int compare(List<String> list1, List<String> list2) {
int size = list1.size();
int diff = 0;
for (int i=0; i<size; i++) {
diff = list1.get(i).compareTo(list2.get(i));
if (diff != 0) {
break;
}
}
return diff;
}
};
Note: this assumes that the rows being compared have the same number of columns, which in my case is a valid assumption.
You want to use comparators.
On the other hand, if you columns are always the same and a fixed number (as in your example), your could create a class Person, extend Comparable and have an ArrayList<Person> which in general is better. Especially for instance if you want those dates to be actual Date objects and not Strings.
Yes, Comparators are the way to sort your list. As you are sorting a List<List<String>>, you need a Comparator<List<String>>.
In Java < 8, create an anonymous implementation of Comparator :
Comparator<List<String>> comparator = new Comparator<List<String>>() {
#Override
public int compare(List<String> o1, List<String> o2) {
int diff = o1.get(0).compareTo(o2.get(0));
if (diff == 0) {
diff = o1.get(1).compareTo(o2.get(1));
if (diff == 0) {
diff = o1.get(2).compareTo(o2.get(2));
}
}
return diff;
}
};
From Java 8, you can write it easier :
Comparator<List<String>> comparator =
Comparator.comparing((List<String> l) -> l.get(0))
.thenComparing((List<String> l) -> l.get(1))
.thenComparing((List<String> l) -> l.get(2));
Then sort :
Collections.sort(list, comparator);
You should consider using a container the sorts automatically such as TreeMap or 'TreeSet'.
http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html
You can customise the sorting by implementing the Comparator interface for your own need.
Java version < 8: could use Comparator and Collections.sort()
Java version >= 8: could use Lambda Expressions
This is a java sample with a generic Comparator>
package test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ArrayListComparator {
public static void main(String[] args) {
ArrayList<String> one=new ArrayList<>();
one.add("John");one.add("2001-01-01"); one.add("Steven");
ArrayList<String> two=new ArrayList<>();
two.add("John");two.add("2001-01-01"); two.add("Albert");
List<ArrayList<String>> container=new ArrayList<ArrayList<String>>();
container.add(one);
container.add(two);
Collections.sort(container, new ArrayComparator());
System.out.println(container.get(0).get(2));
}
public static class ArrayComparator implements Comparator<List<String>> {
#Override
public int compare(List<String> o1, List<String> o2) {
if (o1!=null && o2!=null) {
for (int index=0; index<o1.size(); index++ ) {
if (index<o2.size()) {
String o1Element=o1.get(index);
String o2Element=o2.get(index);
if (o1Element!=null) {
int result=o1Element.compareTo(o2Element);
if (result!=0) {
return result;
}
} else {
return -1;
}
} else {
return 1;
}
}
if (o2.size()>o1.size()) {
return -1;
}
return 0;
}
if (o1==null && o2!=null) {
return -1;
}
if (o1!=null && o2==null) {
return 1;
}
return 0;
}
}
}
As stated by others with java 8 you could use lambda expression.
I need to sort the array list from highest to lowest based on the "value" and im really stuck :( basically in this project, they are gonna run a list of items and this method is supposed to put the one with the highest value first and so fort and im trying to use a selection sort. Thank for you help in advance :) here is what i have at the moment
public void pickMostExpensiveFirst(ArrayList<Item> totalListOfItems)
{
int max, i ,j;
Item temp;
for (i = 0; i < totalListOfItems.size() - 1; i++)
{
max = i;
for (j = i + 1; j < totalListOfItems.size(); j++)
{
if (totalListOfItems.get(max).getValue()
.compareTo(totalListOfItems.get(j).getValue()) > 0)
max = j;
}
temp = totalListOfItems.get(i);
totalListOfItems.set(i, totalListOfItems.get(max));
totalListOfItems.set(max, temp);
}
}
Your problem lies here:
if (totalListOfItems.get(max).getValue().compareTo(totalListOfItems.get(j).getValue()) > 0)
max = j;
here you compare item at position max and j, and if item(max) > item(j), you replace max with j. This is basically searching for LOWEST value, not HIGHEST. Switch it over, and your problem is solved.
Java helps Object Oriented programming, why to implement from scratch when Java collection framework (along with supporting classes) provides ready made proved solutions.
If the objective of your method is just to identify the maximum/ minimum or sort list, then java.util.Collections class provides util methods. only requirement is that your Item class should be (IsA relationship) Comparable, meaning Item should implement Comparable interface. If you do not have control over Item class code, then we can use Interface Comparator to provide comparison rule. the sample code looks as follows.
public static void pickMostExpensiveFirst(ArrayList<Item> totalListOfItems) {
System.out.println(Collections.max(totalListOfItems));
// Collections.sort(totalListOfItems); // to sort with Comparable
// Collections.sort(totalListOfItems, ValueComparator); // to sort with
// Comparator
}
class Item implements Comparable<Item> {
String name;
int value;
public Item(String name, int value) {
this.name = name;
this.value = value;
}
#Override
public int compareTo(Item other) {
return Integer.compare(this.value, other.value);
// return -1 * Integer.compare(this.value, other.value); in case you
//need descending order
}
#Override
public String toString() {
return name + " " + value;
}
}
This question is kind of long... so bear with me please.
I have to convert a SelectionSort method that was covered in my book that was built to sort arrays, and make it generic so that I can enter either doubles or ints into it and have it work.
It doesn't seem to allow generic arrays, so I'm attempting to use an ArrayList. The problem here is since the int and doubles are now in Integer and Double wrappers, it breaks the SelectionSort method.
I've attempted to fix it, but I'm having no luck. I'll post the original SelectionSort method below, and then the class and driver that I'm creating.
Original SelectionSort:
public class SelectionSort {
private int[] data;
private static final Random generator = new Random();
public SelectionSort(int size) {
data = new int[size];
for(int i = 0; i < size; i++) {
data[i] = 10 + generator.nextInt(90);
}
}
public void sort() {
int smallest;
for(int i = 0; i < data.length - 1; i++) {
smallest = i;
for(int index = i + 1; index < data.length; index++) {
if(data[index] < data[smallest]) {
smallest = index;
}
}
swap(i, smallest);
}
}
public void swap(int first, int second) {
int temporary = data[first];
data[first] = data[second];
data[second] = temporary;
}
}
My simple driver program:
public class GenericsDriver {
public static void main(String[] args) {
SelectionSort<Integer> intSort = new SelectionSort<Integer>();
intSort.AddGrade(100);
intSort.AddGrade(90);
intSort.AddGrade(50);
intSort.AddGrade(80);
intSort.AddGrade(95);
intSort.PrintNumbers();
//sort here
intSort.PrintNumbers();
SelectionSort<Double> doubleSort = new SelectionSort<Double>();
doubleSort.AddGrade(100.1);
doubleSort.AddGrade(90.4);
doubleSort.AddGrade(50.7);
doubleSort.AddGrade(100.2);
doubleSort.AddGrade(100.5);
doubleSort.PrintNumbers();
//sort here
doubleSort.PrintNumbers();
}
}
The new class and my attempt to repurpose the SelectionSort method:
import java.util.*;
public class SelectionSort <T> {
private Array<T> numbers;
public SelectionSort() {
numbers = new ArrayList<T>();
}
public void AddGrade(T number) {
numbers.add(number);
}
public void PrintNumbers() {
System.out.println(numbers.toString());
}
public <T extends Comparable<T>> selectionSort() {
int smallest;
for(int i = 0; i < numbers.size(); i++) {
smallest = i;
for(int index = i + 1; index < numbers.size(); index++) {
if(numbers.) {
//I've tried everything here...
//from using number.get(index), and everything else
//I could think of
}
}
}
}
public void swap(int first, int second) {
}
}
As you can see... I haven't had any luck with sort or swap within my new class. I can't get it to work. My instructions have a hint that I should use > in my sort method...but nothing is giving me the ability to use a .compareTo() method.
This is the actual directive from my book:
Write a generic method selectionSort based on the sort program of Fig 19.6 and 19.7 (That's the code I gave above). Write a test program that inputs, sorts and outputs an Integer array and a Float array. Hint: Use > in the type-parameter section for method selectionSort, so that you can use method compareTo() to compare the objects of the type that T represents.
Could someone please give me some guidance here? Thanks.
It seems that you are new to generics. If you want the program to be the way you wrote it, I can point out few mistakes, which you can improve and then try running your program.
In the third code listing where you defined the class as
SelectionSort <T>
The declaration
private Array<T> numbers;
is incorrect because you do not want this Array class, you can instead use the following:
private List<T> numbers;
Also, there is no point declaring the new selectionSort() generic method as
public <T extends Comparable<T>> selectionSort() {
Do you seriously want a Comparable or its sub class to be the return type?
No, you want a List of T to be returned as an output of the selection Sort process.
Please get back if you still have any doubts.
Happy to Help
Dharam
A quick peek at the javadocs (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Double.html ) shows that Double implements the Comparable interface, which means that it will have a compareTo() method.
The point that your book is trying to force you to get your head around is the concept that you can have multiple types (Integer, Double) that implement the same interface (Comparable), and that you can take advantage of that in your code.
So:
Double firstDouble = Double.valueof(42.0);
Double secondDouble = Double.valueof(43.0);
Integer firstInteger = Integer.valueof(42);
Integer secondInteger = Integer.valueof(43);
so you could write: firstDouble.compareTo(secondDouble) and firstInteger.compareTo(secondInteger) - but by implementing your sort on Comparable (instead of Integer, Double, etc...), you can just use:
numbers.get(i).compareTo(numbers.get(i+1));
hth
Use a comparator. This SO answer has some details. You can use the same concept to define your own comparators. That way your sorting algorithm is truly generic and can handle any data type (complex numbers for example)