Using Java. The goal is to search for a value, given as a generic, in an ArrayList, also given as a generic.
My Student class (pertinent parts)
public class Student<T> implements Comparable
{
private String studName;
private Integer gradeAverage;
public Student(String nameIn, int gradeIn)
{
studName = nameIn;
gradeAverage = gradeIn;
}
public int compareTo(Object obj)
{
Student s1 = (Student)obj;
return(this.gradeAverage - s1.gradeAverage);
}
}
My Search; thinking there may be a problem with the generic specifications
public class SearchMethods<T,S>
{
public <T extends Comparable, S extends Comparable> void BinarySearch(T[] inputArray, S searchValue)
{
boolean found = false;
for(int i = 0; i < inputArray.length; i++)
{
T search = inputArray[i];
if(searchValue.compareTo(search) == 0)
{
System.out.println(searchValue + " is at index " + i);
found = true;
}
}
if(found == false)
{
System.out.println(searchValue + " was not found");
}
}
}
And my main()
public static void main(String[] args)
{
Student studentOne = new Student("James",92);
Student studentTwo = new Student("Mary",95);
Student studentThree = new Student("Bobbie",82);
Student studentFour = new Student("Emily",100);
Student studentFive = new Student("Joey",88);
ArrayList<Student> studentList = new ArrayList<Student>();
studentList.add(studentOne);
studentList.add(studentTwo);
studentList.add(studentThree);
studentList.add(studentFour);
studentList.add(studentFive);
SearchMethods<ArrayList, Student> searchMethods = new SearchMethods<ArrayList, Student>();
searchMethods.BinarySearch(studentList, studentOne); //Should print that it was found at index 0
The given compiler error states that an argument mismatch, that ArrayList cannot be converted to T#1[]. But that's the whole point of generics, right?? Interestingly, no analogous error is given for the second type, but maybe the compiler just hasn't read ahead that far.
I'm pretty sure my syntax is OK at the class level, so the error is likely with the calling objects in main(). Though, I could be wrong.
Thanks in advance!
You need to convert arraylist to an array. Check the argument for Binary Search.
Try this:
SearchMethods<ArrayList, Student> searchMethods = new SearchMethods<ArrayList, Student>();
searchMethods.BinarySearch(studentList.toArray(new Student[studentList.size()]), studentOne);
You could also change BinarySearch where you work with an arraylist.
While this is not part of the question, it is important not compute the difference for compareTo or you will get overflow error.
Try this:
class Student<T> implements Comparable
{
private String studName;
private Integer gradeAverage;
public Student(String nameIn, int gradeIn)
{
studName = nameIn;
gradeAverage = gradeIn;
}
public int compareTo(Object obj)
{
Student s1 = (Student)obj;
if (this.gradeAverage < s1.gradeAverage){
return -1;
}
if(this.gradeAverage == s1.gradeAverage){
return 0;
}
return 1;
}
#Override
public String toString(){
return "student name="+studName +" grade average= " + gradeAverage;
}
}
Related
I have created a program that sorts trading cards and places them in a collection that is then compared to other collections to look for duplicates. I have had no problems up until my final toString method. My issue is that I cannot seem to get the return statement to separate the various cards onto their own separate lines.
instead of Alan Turing, Grace Hopper, Ada Lovelace, I need:
Alan Turing
Grace Hopper
Ada Lovelace
Below is a copy of my code. I am fairly new to java so I apologize for any lack of knowledge pertaining to methods specific to this, but I have only found ones using System.out.println, and not mentioning return in any way. My problem lies in the method defined by **. I appreciate any and all help and am sorry if this question is not 100% clear. (I have tried my own research to no avail!)
// First Class
public class Card implements Comparable<Card> {
private String name;
private String nationality;
private int yearBorn;
private int yearDied;
public Card(String name, String nationality, int yearBorn, int yearDied) {
this.name=name;
this.nationality=nationality;
this.yearBorn=yearBorn;
this.yearDied=yearDied;
}
public int compareTo(Card c) {
if (this.name.equals(c.name)) return 0;
else if (this.name.compareTo(c.name)>0) return 1;
else return -1;
}
public String toString() {
return String.format("%s (%d - %d) - %s", name, yearBorn, yearDied, nationality);
}
}
// Second Class
import java.util.ArrayList;
import java.util.List;
public class CardCollection {
private String owner;
private List<Card> myCollection;
public CardCollection(String owner) {
this.owner = owner;
this.myCollection = new ArrayList<>();
}
public boolean addCard(Card c) {
int p = 0;
while (p < myCollection.size()) {
int q = myCollection.get(p).compareTo(c);
if (q == 0) {
return false;
} else if (q > 0) {
myCollection.add(p, c);
return true;
}
p++;
}
myCollection.add(c);
return true;
}
public void removeCard(int r) {
myCollection.remove(r);
}
public int getSize() {
return myCollection.size();
}
public ArrayList<Card> mergeCollections(CardCollection cc) {
ArrayList<Card> dupes = new ArrayList<>();
while (cc.getSize() > 0) {
Card c = cc.myCollection.remove(0);
if (myCollection.contains(c)) {
dupes.add(c);
}
else myCollection.add(c);
}
return dupes;
}
**public String toString() {
String s = "";
for (int i = 0; i < owner.length(); i++) {
s += "-";
}
return String.format("%s\n%s\n%s\n", owner, s, myCollection);**
}
}
// Runner Class
import java.util.ArrayList;
public class CCRunner {
public static void main(String[] args) {
CardCollection c1 = new CardCollection("Alan");
CardCollection c2 = new CardCollection("Grace");
Card turing = new Card("Alan Turing","British",1912,1954);
Card hopper = new Card("Grace Hopper","American",1906,1992);
Card vonneumann = new Card("John Von Neumann","Hungarian",1903,1957);
Card shannon = new Card("Claude Shannon","American",1916,2001);
Card johnson = new Card("Katherine Johnson","American",1918,-1);
Card lovelace = new Card("Ada Lovelace","British",1815,1852);
Card cerf = new Card("Vint Cerf","American",1943,-1);
Card brin = new Card("Sergey Brin","Russian",1973,-1);
c1.addCard(turing);
c1.addCard(vonneumann);
c1.addCard(shannon);
c1.addCard(johnson);
c1.addCard(cerf);
c1.addCard(brin);
c2.addCard(cerf);
c2.addCard(lovelace);
c2.addCard(johnson);
c2.addCard(vonneumann);
c2.addCard(hopper);
System.out.println(c1);
System.out.println(c2);
ArrayList<Card> dupes = c1.mergeCollections(c2);
System.out.println(c1);
System.out.println(c2);
System.out.println("Duplicates:\n-----------");
for (Card c : dupes) {
System.out.println(c);
}
}
}
This is run in a separate class, but I don't think it will elucidate my problem to include it. Let me know if I am wrong.
You can either change your implementation of toString() of your CardCollection class. Examples:
Loop again, this time over the List:
public final String toString() {
String s = "";
for (int i = 0; i < owner.length(); i++) {
s += "-";
}
for (int i = 0; i < myCollection.size(); i++) {
s += "\n" + myCollection.get(i);
}
return String.format("%s\n%s\n", owner, s);
}
Using a stream (requires an additional import java.util.stream.Collectors;):
public final String toString() {
String s = "";
for (int i = 0; i < owner.length(); i++) {
s += "-";
}
return String.format("%s\n%s\n%s\n",
owner,
s,
myCollection.stream()
.map(Card::toString)
.collect(Collectors.joining("\n")));
}
Or you can #Override the toString() method of the ArrayList, also in your CardCollection class. Example:
this.myCollection = new ArrayList<>(){
#Override
public String toString(){
String s = "";
if (size() > 0) s = get(0).toString();
for (int i = 1; i < size(); i++) {
s += "\n" + get(i).toString();
}
return s;
}
};
All examples will result in this for Alan (before the merge):
Alan
----
Alan Turing (1912 - 1954) - British
Claude Shannon (1916 - 2001) - American
John Von Neumann (1903 - 1957) - Hungarian
Katherine Johnson (1918 - -1) - American
Sergey Brin (1973 - -1) - Russian
Vint Cerf (1943 - -1) - American
Note: I'd personally go with changing the implementation of toString() of the CardCollection class. I would also perfer the way tquadrat did it in their answer. The overriding of ArrayList looks to messy in my opinion, and keeping the stringrepresentation in the toString() method makes more sense to me.
Try this as a replacement to the marked toString() implementation:
…
public final String toString()
{
var s = "-".repeat( owner.length() );
var joiner = new StringJoiner( "\n", String.format( "%s%n%s%n", owner, s ), "" );
for( var c : myCollection ) joiner.add( c.toString() );
var retValue = joiner.toString();
return retValue;
}
Basically, the output would look like this:
<owner>
-------
<collectible1>
<collectible2>
<…>
If you are using a Java version before Java 11, you may need to replace var with the respective types.
Is there a way I can sort my teams arraylist by the number of points that team has, so whichever team has the highest points is first, and so on, please dont use comperator, because I don't understand how to use that, here is my code:
import java.util.*;
import java.io.*;
class team {
public int teamNum;
public int points = 0;
public team(int x) {
this.teamNum = x;
}
public team(int x,int y) {
this.teamNum = x;
this.points = y;
}
}
public class Problem9 {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(new File("Test9.txt"));
ArrayList<team> teams = new ArrayList<>();
int counter=0;
while(in.hasNextLine()) {
boolean found = false;
String[] split = in.nextLine().split(" ");
int n1 = Integer.parseInt(split[0]);
int n2 = Integer.parseInt(split[1]);
if (!(n1 == 0 && n2 == 0)) {
if (counter<1) teams.add(new team(n1));
for (int i=0; i<teams.size(); i++) {
if (teams.get(i).teamNum == n1) {
teams.get(i).points+=n2;
found = true;
}
}
if (!found) {
teams.add(new team(n1, n2));
}
}
counter++;
}
for (int k=0; k<teams.size(); k++)
System.out.println(teams.get(k).teamNum + " " + teams.get(k).points);
}
}
There are 2 ways to do sorting on a custom data type :
use Comparator
use Comparable
Using Comparable
class team implements Comparable<team> {
public int teamNum;
public int points = 0;
public team(int x) {
this.teamNum = x;
}
public team(int x,int y) {
this.teamNum = x;
this.points = y;
}
public int compareTo(team t1){
return t1.points - this.points;
}
}
Now use Collections.sort() on the arraylist, which would sort it for you.
Agreed with #sschale, you can't run away from certain methods or libraries just because you do not know how to use it and hence do not want to use it. To help you out I will give you a much simplified form of comparator implementation here:
//Place this between class team and public class Problem9
static class rankcomparator implements Comparator<Team> {
#Override //need to override
public int compare(Team lhs, Team rhs) {
return -compare(lhs.points, rhs.points); //if descending order
//return compare(lhs.points, rhs.points); //if ascending order
}
}
public static void main(String[] args) throws IOException {
//Add this code inside public class Problem9 ...
Collections.sort(teams, new rankcomparator());
}
You really need to learn how a Comparator and the Comparable interface work. I recommend this tutorial on Comparator usage and this tutorial on using natural ordering through the Comparable interface.
Concerning the issue at hand: just add a getScore method to your Team class:
int getScore(){ return this.score;}
Then call:
teams.sort(Comparator.comparing(Team::getScore));
You can reverse the order using:
teams.sort(Comparator.comparing(Team::getScore).reversed());
One last thing: it is convention that class names begin with a capital letter. You should refactor your team class to be Team.
You can also just do that without a comparator because you just have Integers to compare to each other:
teams.sort((Team t1, Team t2) -> (Integer.compare(t1.getScore(), t2.getScore())));
Collections.reverse(teams);
I am studying Java and have been asked to produce methods that can be used in order to gather statistics based off of the student names and marks that are entered. I have worked out how to calculate the top mark but what I need to do is return the name of the student that got the highest mark, how would I do this? I was thinking I could try to return the string before the highest int but I wasn't sure how I would do that.
Edit: Just to make it clear, currently, when END is entered in to the console following the input of data, the top mark is returned - I need to return the mark of the best student.
import java.util.*;
public class Course {
private ArrayList<Student> people = new ArrayList<Student>();
private int passing = 0;
private int failing = 0;
private int top = Integer.MIN_VALUE;
private int sum = 0;
public void add( Student student ) {
people.add( student );
if(student.getMark() >= 40){
passing++;
}
else {
failing++;
}
sum += student.getMark();
if(student.getMark() > top) {
top = student.getMark();
}
}
public int pass() {
return passing;
}
public int fail() {
return failing;
}
public int top() {
return top;
}
public double average() {
return sum / people.size();
}
}
Thanks for any help.
Update: BinaryJudy, I did what you said but I get a 'NoSuchMethod' error for the top name, this is what I changed my code to:
import java.util.*;
public class Course {
private ArrayList<Student> people = new ArrayList<Student>();
private int passing = 0;
private int failing = 0;
private int top = Integer.MIN_VALUE;
private int sum = 0;
private String topName;
public void add( Student student ) {
people.add( student );
if(student.getMark() >= 40){
passing++;
}
else {
failing++;
}
sum += student.getMark();
if(student.getMark() > top) {
top = student.getMark();
}
if(student.getMark() > top) {
top = student.getMark();
topName = student.getName();
}
}
public int pass() {
return passing;
}
public int fail() {
return failing;
}
public String top() {
return topName;
}
public double average() {
return sum / people.size();
}
}
Any idea why? :)
You have already found the student with the top mark. Update the top name with the name of the student when the top mark is found. Finding the top mark results in also finding the name.
String topName;
if(student.getMark() > top) {
top = student.getMark();
topName = student.getName();
}
Note that you're storing a bunch of students who I assume each have a mark for the course. All you need to do is cycle through that Arraylist, and find out who has the highest mark, and return that student.
Something like this may work for you:
public String topStu(ArrayList<Student> list) { // take in any list of students
int topStudentScore = 0; // default value
Student topStudent = null;
for (student x : list) { // cycle through all students in the list
if (x.getMark() > topStudentScore) { // if the score is higher than the current listed score
topStudentScore = x.getMark(); // update the top score
topStudent = x; // update top student
}
}
return topStudent.getName(); // return his name
}
You can easily write this to be a function for a specific course - you can remove the parameter, and directly access the private ArrayList if you want to.
Alternatively, you can write the above function to be a static function that takes any list of students from any course.
If a student is unique in the people list and insert order has no importance, then you can change
ArrayList<Student> people = ...;
By
// Java7 and before
SortedSet<Student> people = new TreeSet<>(new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return s2.getMark()-s1.getMark(); // sorted by decreasing mark
}
});
// Java8
SortedSet<Student> people
= new TreeSet<>(Comparator.comparingInt(Student::getMark).reversed());
Then finding the top student is matter of getting the first from the people set:
Student top = people.first();
As a bonus, you can compute easily the ranking for all student. Adding new student will put them at the right ranking.
Note: Be aware that modifying a student mark after insertion will not change automatically its ranking and should be handled through a sequence of :
Student s = ...;
people.remove(s);
s.setMark(42);
people.add(s);
public class Classroom
{
Student[] students;
int numStudentsAdded;
public Classroom(int numStudents)
{
students = new Student[numStudents];
numStudentsAdded = 0;
}
public Student getTopStudent()
{
int y = 0;
//have to use numStudentsAdded
for ( int i = 0 ; i < numStudentsAdded ; i++)
{
if (students[y].getAverageScore() < students[i].getAverageScore())
{
y = i;
}
}
return students[y] ;
}
public void addStudent(Student s)
{
students[numStudentsAdded] = s;
numStudentsAdded++;
}
public void printStudents()
{
for(int i = 0; i < numStudentsAdded; i++)
{
System.out.println(students[i]);
}
}
}
I'm starting to learn object orientation in my course and we have an object class called students. An object of the studentsclass stores the instance variables: studentName, studentNumber, and studentGPA. I have a boolean method in my object class that determines whether the student is a failing student or not (the student is failing if their GPA is > 2.0) and then I have a method in my worker class that is supposed to accept the array of students objects, and then if the student is failing, it replaces that object with "null".
My problem is that I'm having a hard time replacing the students objects with null, since java keeps throwing me or some such. Here's what I've tried:
public static void removeFailingStudents(Student[] students)
{
int count;
for (count=0; count<students.length; count++)
{
if(students[count].isFailing())
{
students[count] = null;
}
}
}
and
public static void removeFailingStudents(Student[] students)
{
int count;
for (count=0; count<students.length; count++)
{
if(students[count].isFailing())
{
students[count] = "null";
}
}
}
but when I compile/run these attempts it either throws me an exception or it yells at me because it is not of the type Student. How do I set an item in an array of objects to null?? Thanks for the help!
Here's my full code:
public class L2Q1
{
public static void main(String[] parms)
{
process();
System.out.println("\nEnd of processing.");
}
public static void process()
{
Student[] students;
Student[] newStudents;
students = getStudents();
printStudents(students);
printAverageGPA(students);
printHonourStudents(students);
removeFailingStudents(students);
printStudents(students);
newStudents = compactStudents(students);
printStudents(students);
printStudents(newStudents);
}
public static void printStudents(Student[] students)
{
int count;
System.out.println("Students:");
for (count=0; count<students.length; count++)
{
System.out.println(students[count].toString());
}
System.out.println();
}
public static void printAverageGPA(Student[] students)
{
double sumGPA;
int count;
sumGPA = 0;
for (count=0; count<students.length; count++)
{
sumGPA += students[count].getGPA();
}
double average = sumGPA / count;
System.out.println("The average GPA is " + average);
System.out.println();
}
public static void printHonourStudents(Student[] students)
{
int count;
System.out.println("Honour students:");
for (count=0; count<students.length; count++)
{
if(students[count].isHonourStudent())
{
System.out.println(students[count].toString());
}
}
System.out.println();
}
public static void removeFailingStudents(Student[] students)
{
int count;
for (count=0; count<students.length; count++)
{
if(students[count].isFailing())
{
students[count] = null;
}
}
}
public static Student[] compactStudents(Student[] students)
{
Student[] newStudents;
int count1;
int count2;
System.out.println("Compacting failing students.");
System.out.println();
count1 = 0;
for (count2=0; count2<students.length; count2++)
{
}
newStudents = new Student[0];
return newStudents;
}
public static Student[] getStudents()
{
Student[] students = new Student[]
{
new Student(7654321, "Lara Zhivago", 3.75),
new Student(7654322, "Betty Brown", 1.9),
new Student(7654323, "Chris Cross", 0.5),
new Student(7654324, "Dr. Dre", 4.0),
new Student(7654325, "Joe Cool", 2.0)
};
return students;
}
}
/******************************************************************/
/******************************************************************/
class Student
{
private int number;
private String name;
private double gpa;
public Student(int snum, String sname, double sgpa)
{
this.number = snum;
this.name = sname;
this.gpa = sgpa;
}
public double getGPA()
{
return gpa;
}
public boolean isHonourStudent()
{
boolean isHonourStudent = false;
if(getGPA() >= 3.5)
{
isHonourStudent = true;
}
return isHonourStudent;
}
public boolean isFailing()
{
boolean isFailing = false;
if(getGPA() < 2.0)
{
isFailing = true;
}
return isFailing;
}
public String toString()
{
return number + " " + name + " " + gpa;
}
}
Here's the exception message:
java.lang.NullPointerException
at L2Q1.printStudents(L2Q1.java:41)
at L2Q1.process(L2Q1.java:28)
at L2Q1.main(L2Q1.java:13)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
The Problem
You are making elements in your students array null. Then you try to use toString() but on a null element. This is how it looks like: null.toString(), obviously that is bad.
Solution Without ArrayList
On the comments people suggested an ArrayList. I am assuming this is homework and you are forced to use an array, therefore you should do this:
Keep track of the size of the array. Use that to determine how many real elements, non-null elements, you have on the list. Like this:
for(int i = 0; i < arraySize; i++)
{
// Do something with the array here.
}
Make sure you declare arraySize as an instance variable.
private int arraySize = 0;
Remember you will need to increment arraySize for every new element and decrement it every time you null out an element.
Keep in mind that by the time your program finishes your array will have a trail of nulls at the end.
Hackish Solution
In the mean time you can do this to your printStudents() -- this is hackish and only a temporary fix.
public static void printStudents(Student[] students)
{
// Check if the array is null, good practice.
if(students == null)
return;
System.out.println("Students:");
for (int i = 0; i < students.length; i++)
{
// My hack: Check if element is null, if it is then skip it.
if(students[i] == null)
continue;
System.out.println(students[i].toString());
}
System.out.println();
}
This happens because you've already removed some of the students, turning them from Student to null. You're trying to call toString() on one of the non-existing students that are null.
I suggest you replace the array with ArrayList, from which you can actually remove elements. Alternatively, you can rebuild the array when you remove a student.
You are setting a Student object at an index to null, then later in a different method attempting to call toString() on a null object. Using List would help you work with this problem much more elegantly.
Without rewriting the whole code, here is how you could implement List instead:
public static void process() {
List<Student> students = new ArrayList<Student>();
List<Student> newStudents = new ArrayList<Student>();
...
Then when you loop through a List in all your different functions, you would use
for (int count = 0; count < students.size(); count++) {
//do stuff here
}
If you want to remove a student from a list, use
students.remove(count);
To populate the list, use
Student student1 = new Student(7654321, "Lara Zhivago", 3.75);
students.add(student1);
....
I know that this question might have been asked before, but I was not able to find a fit answer. So say I have this array:
String[][] theArray = {
{"james", "30.0"},
{"joyce", "35.0"},
{"frank", "3.0"},
{"zach", "34.0"}};
Is there a way to descendingly sort this array by the second element of each sub-element. So I would get something like this.
theArray = {
{"joyce", "35.0"},
{"zach", "34.0"},
{"james", "30.0"},
{"frank", "3.0"}};
Use Arrays.sort(arr, comparator) with a custom comparator:
Arrays.sort(theArray, new Comparator<String[]>(){
#Override
public int compare(final String[] first, final String[] second){
// here you should usually check that first and second
// a) are not null and b) have at least two items
// updated after comments: comparing Double, not Strings
// makes more sense, thanks Bart Kiers
return Double.valueOf(second[1]).compareTo(
Double.valueOf(first[1])
);
}
});
System.out.println(Arrays.deepToString(theArray));
Output:
[[joyce, 35.0], [zach, 34.0], [james, 30.0], [frank, 23.0]]
Beware:
you will be sorting the array you passed in, Arrays.sort() will not return a new array (in fact it returns void). If you want a sorted copy, do this:
String[][] theCopy = Arrays.copyOf(theArray, theArray.length);
And perform the sorting on theCopy, not theArray.
You must use the Arrays.sort() method. This method takes a Comparator as argument. The sort method delegates to the comparator to determine if one element of the array must be considered bigger, smaller or equal to another element. Since every element of the outer array is an array, the comparator will have to compare arrays (of Strings).
The arrays must be compared based on the value of their second element. This second element is a String which in fact represents a double number. So you'll have to transorm the strings into numbers, else the order will be lexicographical (20 come before 3) rather than numerical.
The comparator could thus look like this :
public class StrinArrayComparator implements Comparator<String[]> {
#Override
public int compare(String[] array1, String[] array2) {
// get the second element of each array, andtransform it into a Double
Double d1 = Double.valueOf(array1.[1]);
Double d2 = Double.valueOf(array2.[1]);
// since you want a descending order, you need to negate the
// comparison of the double
return -d1.compareTo(d2);
// or : return d2.compareTo(d1);
}
}
If you want to move away from arrays, here's a variation that uses List<Record> and a RecordComparator that implements Comparator<Record>.
Console:
joyce 35.0
zach 34.0
james 30.0
frank 23.0
Code:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/** #see http://stackoverflow.com/questions/5064027 */
public class ComparatorTest {
public static void main(String[] args) {
List<Record> list = new ArrayList<Record>(Arrays.asList(
new Record("james", "30.0"),
new Record("joyce", "35.0"),
new Record("frank", "23.0"),
new Record("zach", "34.0")));
print(list, Sort.DESCENDING, Field.D);
}
private static void print(List<Record> list, Sort s, Field f) {
RecordComparator rc = new RecordComparator(s, f);
Collections.sort(list, rc);
for (Record r : list) {
System.out.println(r);
}
}
}
class Record {
private String s;
private Double d;
public Record(String name, String number) {
this.s = name;
this.d = Double.valueOf(number);
}
#Override
public String toString() {
return s + " " + d;
}
public int compareTo(Field field, Record record) {
switch (field) {
case S: return this.s.compareTo(record.s);
case D: return this.d.compareTo(record.d);
default: throw new IllegalArgumentException(
"Unable to sort Records by " + field.getType());
}
}
}
enum Sort { ASCENDING, DESCENDING; }
enum Field {
S(String.class), D(Double.class);
private Class type;
Field(Class<? extends Comparable> type) {
this.type = type;
}
public Class getType() {
return type;
}
}
class RecordComparator implements Comparator<Record> {
private Field field;
private Sort sort;
public RecordComparator(Sort sort, Field field) {
this.sort = sort;
this.field = field;
}
#Override
public final int compare(Record a, Record b) {
int result = a.compareTo(field, b);
if (sort == Sort.ASCENDING) return result;
else return -result;
}
}
You seem to be living in object denial. Those inner arrays look a lot like information about a Person (with the name and some value, maybe a score).
What you'd want to do is to write a custom class to hold that information:
public class Person {
private final String name;
private final double score;
public Person(final String name, final double score) {
this.name=name;
this.score=score;
}
public String getName() {
return name;
}
public double getScore() {
return score;
}
}
Then, when you want to sort them, you simply implement a Comparator<Person> that specifies how you want them sorted:
public PersonScoreComparator implements Comparator<Person> {
public int compare(Person p1, Person p2) {
return Double.compare(p1.getScore(), p2.getScore());
}
}
Alternatively, you could have the Person class itself implement Comparable<Person> by adding this method:
public int compareTo(Person other) {
return Double.compare(getScore(), other.getScore());
}
-Create list out of this array using Arrays.toList()
-Design comparator using java.lang.comparator and write logic for sorting every even elements
There are several sort methods in java.util.Arrays. Two of them take custom Comparators. Simply provide a comparator comparing the second element of the inner arrays.
public static void main(String[] args)
{
String Name[][]={{"prakash","kumar"},{"raj","kappor"},{"vinod","bhart"}};
String str[]=new String[2];
for(int j=0; j<Name.length;j++)
{
for (int i=0 ; i<2; i++)
{
str[i]=Name[j][i];
}
for(int i=0;i<str.length;i++)
{
for(int k=i+1;k<str.length;k++)
{
if(str[i].compareTo(str[k])>0)
{
String temp= str[i];
str[i]=str[k];
str[k]=temp;
}
}
System.out.print(str[i]+ " ");
}
System.out.println();
}
}
}
/**
*
* #param array - 2D array required to be arranged by certain column
* #param columnIndex - starts from 0; this will be the main comparator
* #param hasHeaders - true/false; true - ignore the first row. False -
* first row it's also compared and arranged
* #return - the new arranged array
*/
private String[][] arrangeArray(String[][] array, int columnIndex, boolean hasHeaders) {
int headersExists = 0;
if (hasHeaders) {
headersExists = 1;
}
for (int i = headersExists; i < array.length; i++) {
for (int j = headersExists; j < array.length; j++) {
if (array[i][columnIndex].compareTo(array[j][columnIndex]) < 0){
String[] temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}