I always thought that any array type is like a different class but it seems like any reference type arrays are also considered an object of Object[] and their superclasses' array form. (Is this exactly right?)
Consider the following array
Integer[] numbers = { 20, 15, 10, 5 };
When I pass this array to Arrays.sort which expects an Object[] value, it works fine. But an Object doesn't have any method to compare, how does it know which compare method to use?
Integer implements Comparable<Integer> which defines a natural ordering on Integers. Calling sort without a Comparator relies on the elements of the array to implement Comparable, and uses the compareTo method of that interface.
Arrays.sort is used for primitive types and the Object as well.
As per the array elements type those are being sorted by using sort1 but these sort1 methods are private.
If you are tying to sort int array. So you will use method sort(int[] a). It will call the private method sort1:
private static void sort1(int x[], int off, int len) {...}
And this method description is Sorts the specified sub-array of integers into ascending order.
If you are going to sort Object it will call mergeSort method.
But When you look at Integer class file, it implements Comparable<Integer> (Remember although it's subclass of Object):
public final class Integer extends Number implements Comparable<Integer>
So here you don't want to use the Arrays.sort method. By using the compareTo(Integer anotherInteger) method the array can be sorted.
Related
This is an assignment, I can't post the entire code, but I really need understand what I'm doing wrong. I'm sure its a rookie mistake.:(
I had to construct a custom sort method,that sorts specific properties of my arraylist objects. I've created different Comparators to address the different elements within the objects I want sorted.
*edit added more code
sort utility method (parameters required):
public class CarManage{
private ArrayList <Car> carList; //carList defined
public class Sorts {
public static void sorts(Car[]carList, int size, Comparator <Car> someComparator) //given parameters not allowed to modify
{
//sorts arrayList(carList) objects using an insertion sort algorithm.
}
}
} //end class
I try call the sort method, to specify which properties I need sort, but alas it rejects the first parameters.
public void sortByVinNumber(){
VinNumComparator vnc = new VinNumComparator();//one of many comparators
Sorts vncSort = new Sorts();
for(int i = 0; i < carList.size(); i++){
if(vnc.compare(carList.get(i-1), carList.get(i)) > 0){
vncSort.sorts(Car[]carList, 2, vnc);//not working here rejects first parameter
///vncSort.sorts(carList,2,vnc)///doesn't work
}
}
}
I'm not sure why it won't accept my parameter? Could it be a pass-reference mistake? Or am I possibly calling the method wrong?
You need to call the method like so:
vncSort.sorts(carList, 2, vnc);
Also, it seems like you're confusing an array with an ArrayList. An Array of Car would be Car[]. An ArrayList<Car> is a List which accepts and produces Car types. The reason it's called ArrayList is because it's backed internally by an array.
I have an array which contains values pawnArray. I need to find the highest value in pawnArray so using a custom class method getPawn() I retrieve the highest value but I do
public static Pawn getPawn(Array<Pawn> strollpawns) {
Array<Pawn> pawns = strollpawns;
pawns.sort();
Pawn best = pawns.get(0);
return best;
}
I hence need to copy the array since this method doesn't work. How can I make a copy of this array?
If your problem is with Java arrays (the syntax is Pawn[]) then you have methods in class java.util.Arrays for many different operations on them. What you are asking for could be accomplished with:
Pawn[] newArr = Arrays.copyOf(oldArr, oldArr.length);
Or, since array classes implement Cloneable, also with:
Pawn[] newArr = (Pawn[]) oldArr.clone(); // I don't remember if the cast is necessary
Note that both of these provide shallow copies, that is, the arrays are independent of each other (you can sort one and the indexes in the other are unaffected) but their contents are not.
EDIT: it has been kindly pointed out to me that your Array<T> is actually a class in libgdx. Looking at the documentation, then, you could simply use the constructor taking another instance of Array to create your shallow copy, since the doc says that the new instance will have the same type of backing array (not the same instance). For example:
Array<T> newArr = new Array<>(oldArr); // oldArr can be either Array<? extends T> or T[]
I'm adding a separate answer to this, since you want to copy your array and sort it in order to retrieve the highest value. My other answer deals with copying the array, while tjago's answer deals with sorting with a custom Comparator in order to customize what the "max value" is. However, it seems that the libgdx Array<T> class has a method to do just what you want, without having to make a sorted copy of the array.
This solution saves you code, memory and time if you only need one value from the sorted array: the minimum, maximum, whatever. If you need more than one, it is likely that sorting the array will be faster.
The method I'm talking about is Array.selectRanked, which returns the nth element according to the provided Comparator. There is another method selectRankedIndex which returns the index of that element instead of the object itself. You could use it like this:
// If Pawn implements Comparable<Pawn>:
Pawn minVal = arr.selectRanked(Comparator.naturalOrder(), 1);
Pawn maxVal = arr.selectRanked(Comparator.naturalOrder(), arr.size);
// If it does not implement Comparable, you need to provide a Comparator<Pawn>:
// Assuming Pawn has an "int getValue()" method that we want to compare:
Pawn minVal = arr.selectRanked(Comparator.comparingInt(Pawn::getValue), 1);
// You could also write your own implementation directly:
Comparator<Pawn> comp = (a,b) -> /* your int-returning logic here */;
Pawn minVal = arr.selectRanked(comp, 1);
It seems you have a java related problem. To help you with sorting In java object programming there exist concept of method overriding and interfaces.
Special interface for sorting is Comparator, you can either put him inline in method like this.
Collections.sort(pawns ,new Comparator<Student>(){
public int compare(Pawn1 p1,Pawn2 p2){
// Write your logic here.
//ie.:
return p1.score - p2.score;
//or for different order
return p2.score - p1.score;
}});
if this comparator return value == 0 means the value are equal;
if value < 0 means p1 is bigger than p2, therefore swap them.
Or put him inside your Object class like:
Class Pawn implements Comparator {
private String name;
private Position[][] posXY;
private int value;
....
Pawn() { ... }
...
public int compare(Pawn1 p1,Pawn2 p2){
return p1.value- p2.value;
}
}
then in your code you can call as you originally intended:
pawns.sort();
Pawn best = pawns.get(0);
and as expected you should get an maximum value Pawn from ArrayList.
The above code is just sample and requires tunning. But You should get an good overview now that Java has no idea how to sort Objects defined by a programmer unless he implements the Comparator logic for Collection sorting.
for external reference I suggest running a simple example on tutorialpoint
Answer to your question: How can I create copy of a libgdx array
Array<Pawn> pawns = new Array<Pawn>(strollpawns);
or if the pawns Array object already exists
pawns.clear();
pawns.addAll(strollpawns);
The first solution will create a new Array object that will be deleted on completion of the function, meaning time lost by garbage collector!
But I agree with Tenfour04: Duplicating an array and sorting it is a very expensive way to select the biggest value.
I'm working on a project where I need to be able to sort an ArrayList of Car objects by price. In my Car class, I have
public class Car implements Comparable
and in the body of the code is the compareTo method:
public int compareTo(Object o)
{
Car rhs = (Car)o;
if (price > rhs.price)
return 1;
else if (price < rhs.price)
return -1;
else
return 0;
}
I just don't understand how to implement this method to sort by price- what does carList need to be compared to? I know this isn't correct but so far this is the sorting method.
public void sortByPrice()
{
Collections.sort(carList.compareTo(o));
}
Two problems: one syntatical and one conceptual.
The first issue is that while your compareTo is technically correct, you want to type-bind it to Car instead of Object.
public class Car implements Comparable<Car>
Inside of your compareTo method you'd then substitute Object for Car. You would also want to check for null.
The second is that sortByPrice sounds specific, but since compareTo is comparing based on price, that's somewhat okay.
All you'd need to do is call Collections.sort on the actual collection:
Collections.sort(carList);
Normally, one sorts a collection using
Collections.sort(collection)
while collection has to implement Comparable and sort uses the compareTo method to sort collection.
Your Car class must implement Comparable<Car>. Then your compareTo method will have signature:
public int compareTo(Car other) {}
As per the documentation, this method should:
Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
Then given a List<Car>, say list, you can call Collections.sort(list).
You're almost done! Only call to Collections.sort(carList); and that will by itself, use the overridden compareTo.
Actually, when you're not implementing compareTo, you'll have the very basic implementation, and calling Collections.sort(..) will use the basic implementation, which is comparing pointers in that case.
I use this function in java:
Collections.sort(an Arraylist, new CustomComparator);
The compare method in CustomComparator class will return an int. What this means to the sort procedure? what's the number of this value and how will affect the sorting procedure?
More specifically i want in compare method to compare two values. Here is my code:
import java.util.Comparator;
public abstract class CustomComparator implements Comparator<HLine> {
#Override
public int compare(HLine hl1, HLine hl2) {
return hl1.y < hl2.y;
}
}
and i call for sorting:
Collections.sort(hlines, new comparator());
hlines is an Arraylist of a object's with a Point and two doubles. I want to compare the second double in two object's.
Basically, as stated in the Javadoc of Comparator.compare and Comparable.compareTo these methods return
a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
Meaning that if you call
new Integer(1).compareTo(0)
it will return a negative integer, which indicates, that 0 has to be ordered before 1.
new Integer(1).compareTo(1)
it will return 0, which indicates, that both values has to be ordered on the same level.
new Integer(1).compareTo(2)
it will return a positive integer, which indicates, that 2 has to be ordered after 1.
To fix your codesample, you need to rewrite compare() so it will return an Integer, as it is now it returns a boolean and will not compile.
Because you are trying to compare doubles you can simply change to
#Override
public int compare(HLine hl1, HLine hl2) {
return hl1.y - hl2.y;
}
sort() method sort the elements but first they are compared.For the comparison purpose, sort() method can use compare() or compareTo() methods.
Now, if you want to sort the elements on the basis of only one attribute the use compareTo() method of comparable interface.
And if you want to sort the elements on the basis of more than one elements then use cmopare() method of comparator interface.
I have a Sorts class that sorts (based on insertion sort, which was the assignment's direction) any ArrayList of any type passed through it, and uses insertion sort to sort the items in the list lexicographically:
public class Sorts
{
public static void sort(ArrayList objects)
{
for (int i=1; i<objects.size(); i++)
{
Comparable key = (Comparable)objects.get(i);
int position = i;
while (position>0 && (((Comparable)objects.get(position)).compareTo(objects.get(position-1)) < 0))
{
objects.set(position, objects.get(position-1));
position--;
}
objects.set(position, key);
}
}
}
In one of my other files, I use a method (that is called in main later) that sorts objects of type Owner, and we have to sort them by last name (if they are the same, then first name):
Directions: "Sort the list of owners by last name from A to Z. If more than one owner have the same last name, compare their first names. This method calls the sort method defined in the Sorts class."
What I thought first was to get the last name of each owner in a for loop, add it to a temporary ArrayList of type string, call Sorts.sort(), and then re-add it back into the ArrayList ownerList:
public void sortOwners() {
ArrayList<String> temp = new ArrayList<String>();
for (int i=0; i<ownerList.size(); i++)
temp.add(((Owner)ownerList.get(i)).getLastName());
Sorts.sort(temp);
for (int i=0; i<temp.size(); i++)
ownerList.get(i).setLastName(temp.get(i));
}
I guess this was the wrong way to approach it, as it is not sorting when I compile.
What I now think I should do is create two ArrayLists (one is firstName, one is LastName) and say that, in a for loop, that if (lastName is the same) then compare firstName, but I'm not sure if I would need two ArrayLists for that, as it seems needlessly complicated.
So what do you think?
Edit: I am adding a version of compareTo(Object other):
public int compareTo(Object other)
{
int result = 0;
if (lastName.compareTo(((Owner)other).getLastName()) < 0)
result = -1;
else if (lastName.compareTo(((Owner)other).getLastName()) > 0)
result = 1;
else if (lastName.equals(((Owner)other).getLastName()))
{
if (firstName.compareTo(((Owner)other).getFirstName()) < 0)
result = -1;
else if (firstName.compareTo(((Owner)other).getFirstName()) > 0)
result = 1;
else if (firstName.equals(((Owner)other).getFirstName()))
result = 0;
}
return result;
}
I think the object should implement a compareTo method that follows the normal Comparable contract--search for sorting on multiple fields. You are correct that having two lists is unnecessary.
If you have control over the Owner code to begin with, then change the code so that it implements Comparable. Its compareTo() method performs the lastName / firstName test described in the assignment. Your sortOwners() method will pass a List<Owner> directly to Sorts.sort().
If you don't have control over Owner, then create a subclass of Owner that implements Comparable. Call it OwnerSortable or the like. It accepts a regular Owner object in its constructor and simply delegates all methods other than compareTo() to the wrapped object. Its compareTo() will function as above. Your sortOwners() method will create a new List<OwnerSortable> out of the Owner list. It can then pass this on to Sorts.sort().
Since you have an ArrayList of objects, ordinarily we would use the Collections.sort() method to accomplish this task. Note the method signature:
public static <T extends Comparable<? super T>> void sort(List<T> list)
What's important here is that all the objects being sorted must implement the Comparable interface, which allows objects to be compared to another in numerical fashion. To clarify, a Comparable object has a method called compareTo with the following signature:
int compareTo(T o)
Now we're getting to the good part. When an object is Comparable, it can be compared numerically to another object. Let's look at a sample call.
String a = "bananas";
String b = "zebras";
System.out.println(a.compareTo(b));
The result will be -24. Semantically, since zebras is farther in the back of the dictionary compared to bananas, we say that bananas is comparatively less than zebras (not as far in the dictionary).
So the solution should be clear now. Use compareTo to compare your objects in such a way that they are sorted alphabetically. Since I've shown you how to compare strings, you should hopefully have a general idea of what needs to be written.
Once you have numerical comparisons, you would use the Collections class to sort your list. But since you have your own sorting ability, not having access to it is no great loss. You can still compare numerically, which was the goal all along! So this should make the necessary steps clearer, now that I have laid them out.
Since this is homework, here's some hints:
Assuming that the aim is to implement a sort algorithm yourself, you will find that it is much easier (and more performant) to extract the list elements into an array, sort the array and then rebuild the list (or create a new one).
If that's not the aim, then look at the Collections class.
Implement a custom Comparator, or change the object class to implement Comparable.