How to sort object array? [duplicate] - java

This question already has answers here:
How to sort an array of objects in Java?
(11 answers)
Sort ArrayList of custom Objects by property
(29 answers)
Closed 8 years ago.
I have an object array like
Player p[] = new Player[t];
And every object has an integer variable and a name variable.
public class Player {
public String player_name;
public int number;
}
After getting input from user how can I sort this object array according to their number variable?

With Java SE 8 try something like (untested):
Arrays.stream(p).sorted((p1, p2) -> Integer.compare(p1.number, p2.number)) .collect(Collectors.toList())
Edit
On second thought this might be more efficient in this case, as it doesn't create a new array/ collection:
Arrays.sort(p, (p1, p2) -> Integer.compare(p1.number, p2.number));

The easiest way is to make Player implement Comparable<Player>, and implement the compareTo(Player) method inside Player:
public int compareTo(Player player) {
return this.number-player.number;
}
Then, wherever you want to sort the array, just call Arrays.sort(p);

Create a class that implements Comparator<Player>, called say PlayerComparator. Implement the interface by creating a compare method that takes two Players. Return a negative number, zero, or a positive number, depending on whether the first Player is considered less than, equal to, or greater than, the second Player.
Then you can create your PlayerComparator and pass it (along with your array) to Arrays.sort.

let your custom class implements Comparable interface and then you can use java Collection to sort your array (Arrays.sort() function)
public class Player implements Comparable<Player> {
public String player_name;
public int number;
#Override
public int compareTo(Player object) {
return this.player_name.compareTo(object.player_name);
}
}
sort
Player p[] = new Player[t];
// do stuff
Arrays.sort(p);

You'd need to have a getter on the number variable for this to work, like:
public class Player {
public String player_name;
public int number;
public int getNumber() {
return number;
}
}
Then, as of Java 8, you can sort it by using the Comparing factory class:
Player[] p = new Player[t];
Arrays.sort(p, Comparator.comparingInt(Player::getNumber));
This will:
Create a Comparator<Person>, by comparing no the getNumber method.
What you see here is a method reference, which is shorthand for the lambda p -> player.getNumber(), which maps the player to the number.

Related

Using foreach loop with methods in another class (Java) [duplicate]

This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 6 years ago.
I have a program that creates a couple objects and adds each one to an ArrayList, then is supposed to loop over each object in the ArrayList and use a getter from another class within the project to display information on each object. I can't get the objects in my foreach loop to use any of the methods in my other class. Here is my main, including the trouble loop at the bottom:
import java.util.ArrayList;
public class ITECCourseManager {
public static void main(String[] args) {
ArrayList ITECCourse = new ArrayList();
ITECCourse infotech = new ITECCourse("Info Tech Concepts", 1100, 5, "T3050");
infotech.addStudent("Max");
infotech.addStudent("Nancy");
infotech.addStudent("Orson");
ITECCourse.add(infotech);
ITECCourse java = new ITECCourse("Java Programming", 2545, 3, "T3010");
java.addStudent("Alyssa");
java.addStudent("Hillary");
ITECCourse.add(java);
for (Object course : ITECCourse) {
System.out.println("Name: " + course.getName());
}
}
}
And here is the other class in my project with the method I need to use:
public class ITECCourse {
public String name;
public int code;
public ArrayList<String> students;
public int maxStudents;
public String room;
ITECCourse(String courseName, int courseCode, int courseMaxStudents, String roomNum) {
name = courseName;
code = courseCode;
maxStudents = courseMaxStudents;
students = new ArrayList<String>();
room = roomNum;
}
public String getName() {
return name;
}
If I replace course.getName() with java.getName(), the code works. I'm confused why I can't use a foreach loop across the ArrayList to use the getter for each object, when I am able to call the object and use the method directly from the same place in the code.
Edit: Thank you for the answers, simple mistake only had to make two/three changes: declare ArrayList<ITECCourse> at the beginning, change Object in for loop to ITECCourse, and of course change my arraylist from ITECCourse to ITECCourseList so there isn't confusion with my ITECCourse class.
The call to course.getName() doesn't work because you've defined course as an Object in your loop and Object doesn't have the method getName(). If you add a type parameter to your ArrayList declaration such as ArrayList<ITECCourse>, then you can iterate over the list of ITECCourse instances rather than Object.
On a side note, naming your variable ITECCourse will just lead to confusion because it's the same as your class. Might be better to name your variable something like itecCourseList.

compareTo sets 10 before 2 when sorting on value

Let me give you an example for what i'm trying to achieve. Look only to the numbers because it's a card game.
I have:
harten5 klaveren4 klaveren7 schoppen5 ruiten5 schoppen2 klaverenheer schoppenheer schoppendame schoppen6 klaverenboer schoppen8 ruitenheer klaveren6...
I want to sort this on the value to:
schoppen2 harten2 ruiten2 klaveren2 ruiten3 harten3 schoppen3 klaveren3 klaveren4 harten4 schoppen4 ruiten4 harten5 schoppen5 ruiten5...
But i get the 10 before the 2 like this:
schoppen10 ruiten10 harten10 klaveren10 schoppen2 harten2 ruiten2 klaveren2 ruiten3 harten3 schoppen3 klaveren3...
This is my basic compareTo Method:
#Override
public int compareTo(Card p) {
return this.value.compareTo(p.value);
}
Because String's (I guess this.value is String) compareTo compares lexicographically, whilst you want numerically. So you have to reimplement it, take substring (or find the last part which is a digit, convert it to Integer and then user compareTo on that Integer.
In general, I think your class Card could be improved a bit. In particular, I would rewrite it:
class Card {
private String value;
private Integer rank;
...
public int compareTo(Card c) {
// Additional logic if you need to consider
// also value (suite) in comparison
return this.rank.compareTo(c.rank);
}
}
But you can also use an enum for this purpose.
String java API compareTo
I'm guessing you want the reverse order? If so, then just change your implementation to this:
#Override
public int compareTo(Card p) {
return p.value.compareTo(this.value);
}
It really depends on what the type of "value" is and how the "compareTo" is implemented. Alternatively, you could just do this if "value" is an integer:
#Override
public int compareTo(Card p) {
return this.value - p.value;
}
I believe your value is stored as an String. If you do not want to change the data type of value, you can implement the compareTo method in the following way:
public int compareTo(Card p) {
return Integer.parseInt(this.value).compareTo(Integer.parseInt(p.value));
}

How to create an equals method that compares two object arrays of a class?

I am trying to create a equals method that compares two objects. The thing is, I'm a bit a of new to this stuff so I'll try to explain my goal as easy as possible.
public class A {
...
}
public class B {
private A[] arr = new A[10];
public boolean equals(A[] temp) {
//compare
}
}
Assume the code above is a summary of what I have. Now, assume I had: arr.equals(Obj)
Obj being another A[] object. Now in my equals statement, I want to reference the original arr array, how do I go about doing that?
For example, let's say I wanted to compare arr's length to temp's length (aka Obj's length), how would I do that? I know it would be something like (temp.length == arr.length) but how do I access arr when I pass it through by doing arr.equals(obj)?
EDIT: Just to clarify, assume the objects aren't simple arrays. So for instance, class A could have a Name, a Type (Both Strings) and possibly a Quantity (an int), so I wouldn't be able to simply compare them like they're two normal arrays.
Thanks!
You can use java.util.Arrays.equals(Object[] a, Object[] a2) which tests if the two specified arrays of Objects are equal to one another
Use the keyword this, which always represents the object you are applying the method to (immediately before the dot). For example:
public boolean equals(A[] temp) {
return this.length == temp.length ;
}
Now, in the particular case of your code, you are not defining method equals as part of class A, but of a class B whose instances contain arr. Then, the solution would be:
public boolean equals(A[] temp) {
return this.arr.length == temp.length ;
}
Write a equals mwthod in your class A
public class A {
...
//Override equals method.
}
Now if you want to compare 2 arrays of class A you can simply use java.utils.Arrays.equals(A a1[], A a2[]);
You have to override equals method in class A coz java.utils.Arrays.equals internally uses class A's equals.
Here is an example, go through it.

Is there is a built-in method to sort a 2D array directly?

Is there is a built-in method in Java to sort a 2D array directly
For example: if I have an array of first name & phone number, can I sort it according to the first name while each name will keep it's phone number using built-in function?
Is your data structure [[name1, name2, ...], [phone1, phone2,...]] or [[name1, phone1], ...]? If it's the latter, you can use a comparator.
class NameAndPhoneComparator implements Comparator<String[]> {
public int compare(String[] o1, String[] o2) {
int c = o1[0].compareTo(o2[0]);
if (c != 0) return c;
return o1[1].compareTo(o2[1]);
}
}
Then use Arrays.sort
Make your 2d Array into a 1D array of the below class, then use built in methods with a custom Comparator to do the sorting. You could also make this class Comparable to itself.
class Person{
public String name;
public String phNumber;
}
Alternatively use a TreeMap,as sansix suggests, with the key as the name and value as phNumber. There would be no need for a comparator any more, and the Data will always be sorted.

Function with multiple outputs in Java [duplicate]

This question already has answers here:
How to return multiple objects from a Java method?
(25 answers)
Closed 9 years ago.
How to create a JAVA function with multiple outputs?
Something like:
private (ArrayList<Integer[]>, int indexes) sortObjects(ArrayList<Integer[]> arr) {
//...
}
Java's not like Python - no tuples. You have to create an Object and wrap all your outputs into it. Another solution might be a Collection of some sort, but I think the former means better encapsulation.
In some cases it is possible to use method arguments to handle result values. In your case, part of the result is a list (which may be updated destructively). So you could change your method-signature to the following form:
private int sortObjects(ArrayList<Integer[]> input, ArrayList<Integer[]> result) {
int res = 0;
for (Integer[] ints : input) {
if (condition(ints) {
result.add(calculatedValue);
res++
}
}
return res;
}
You cannot, you can either
Create a wrapper return object
Create multiple functions
Use an object as return value.
class SortedObjects { private ArrayList<Integer[]> _first; int _indexes; ...getter/setter/ctor... }
private SortedObjects sortObjects(ArrayList<Integer[]> arr) { ... }
You cannot.
The simple solution is to return an array of objects. A more robust solution is to create a class for holding the response, and use getters to get the individual values from the response object returned by your code.
You have to create a class which includes member variables for each piece of information you require, and return an object of that class.
Another approach is to use an Object which wraps the collection.
class SortableCollection {
final List<Integer[]> tables = ...
int indexes = -1;
public void sortObjects() {
// perform sort on tables.
indexes = ...
}
}
As it operates on a mutable object, there is no arguments or return values.

Categories