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.
Related
I have a class named MyVisitor that extends another class named Value. In one of my methods in MyVisitor, I have to store an array of Values in a HashMap. However, since the MyVisitor only extends Value, I can't return Value[ ] in the HashMap. Due to my limited knowledge on Java this is the solution I found:
In my Value class, I have:
public static int x;
public static Value ARRAY = new Value(new Object[x]); // I assume this would return an array of Objects of size x?
public Object[] objArray(){
return (Object[])value;
}
In MyVisitor class, I have this HashMap:
public Map<String, Value> array_memory = new HashMap<String, Value>();
In MyVisitor class, I have a method named array that uses Value.ARRAY like so:
Value.x = x; //Would change the value of public static int x in class Value
return array_memory.put(id, Value.ARRAY);
I have another method named arrayDec that calls array and does the following:
array(ctx);
String key = ctx.ID().getText();
Object[] val = array_memory.get(key).objArray();
System.out.println(val.length);
val.length prints 0
I have the following question:
Does = new Value(new Object[Value.x]); actually create an array of Objects of size x and masks it as Value?
Also, does Value.ARRAY actually return an array of Objects of size x?
Why does val.length return 0?
Confused? yeah me too :(
Also, if you're wondering why I'm doing this, I have a project in one of my courses that requires us to create our own compiler/interpreter. I'm trying to implement arrays. I'm using antlr4 to help me with it (thus the ctx.ID().getText() in one of the snippets there)
Any help would be appreciated. And if you have a better idea of how I should implement this I'm open to suggestions. Or if you know any links about implementing arrays in antlr4 that would be awesome as well. Thanks!
No. It creates an instance of Value. This instance might hold an array of Object if you have defined a constructor that takes an Object array as a parameter and assign that parameter to a member.
No. It returns an instance of Value
Impossible to say. Your code doesn’t explain how the member ‘value’ is defined or assigned.
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 know how to find minimum and maximum in an array. If a method lets say was called fMax():
public static double fMax(Object[] stuff)
The parameter is an array object how would I go about finding the max of this array? I cannot just do. Okay so how would I do this if I want the method to return a double and if the memory hasnt been allocated for the parameter named stuff then it will return the value NEGATIVE_INFINITY in the Double class, otherwise the return value will be the maximum value from the elements in the stuff array
Object max = stuff[0];
for (int i = 0; i < stuff.length; i++) {
if (data[i] > max) {
max = stuff[i];
}
}
To find the maximum of something, either
a) that something needs to implement the Comparable interface
b) you need to have some sort of explicit criteria for determining what maximum is, so you can put that in an instance of Comparator
Object itself isn't going to have anything useful for sorting. If you subclass object, you could sort based on the components of that object.
public class Example implements Comparable
{
int sortableValue = 0;
public Example (int value)
{
this.sortableValue = value;
}
public int compareTo(Example other)
{
return Integer.compare(this.sortableValue, other.sortableValue);
}
}
That's an object definition that has a natural sorting order. Java can look at that with any of the built in sorting algorithms and know the order they belong in.
If you don't provide java with a means of determining how an object has greater or lesser relative value compared to another object of the same type, it won't figure it out on its own.
Object is not comparable, you need a definite type if you want to compare values, sort or find something.
Streams are the most powerful, versatile tools for the job, this here will solve your problem if your want to find min/max of an array of Double :
Double[] arr = {1d, 2d, 3d, 4d};
Double min = Arrays.asList(arr).stream().parallel().min(Double::compare).get();
Double max = Arrays.asList(arr).stream().parallel().max(Double::compare).get();
String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
Now, just compare the new primitive array that we made from the object. If you don't need the object after this, and you aren't planning on returning an array object, then make your original array null, to take up less memory.
Check this:
How to compare two object arrays in Java?
I have the following objects:
public class Shipping {
String name;
List<Method> methods;
}
public class Method {
String serviceType;
String cost;
}
I have:
List<Shipping> shippings;
I would like to sort the shipping by the method that returned the cheapest cost.
Example:
shipping: "Josh" with 2 methods: "Premium","5" and "Basic","3"
shopping: "Nash" with 2 methods: "Prem", "7" and "Base","2"
will sort it like this:
shopping: "Nash" with 2 methods: "Base","2" and "Prem", "7"
shopping: "Josh" with 2 methods: "Basic","3" and "Premium","5"
I need it to return the method that has the cheapest method cost as the first one, while sorting also the methods to have the cheapest one first.
What's the best way to do it? I am using Java 8 if it has a better solution, and have guava library
EDIT:
cost is a float number. I need to leave it as String as it's an object that I pass to REST api and wouldn't like client side to parse it.
We will assume all the shippings have at least 1 method. So you want the methods of the shippings to be sorted by cost. So let's do that:
shippings.forEach(shipping -> {
shipping.getMethods().sort(Comparator.comparing(Method::getCost));
});
Then you want the list of shippings to be sorted by the lowest cost of their methods. The lowest cost is the cost of the first method, since they're now sorted:
shippings.sort(Comparator.comparing(shipping -> shipping.getMethods().get(0).getCost()));
Note that this assumes that you want the costs to be compared lexicographically. If, as I suspect, the cost is in fact a number, then it should be stored as such in the Method class, and not as a String. So make it an Integer or a BigDecimal, or whatever the appropriate type is.
You need either a comparator or implement Comparable for Method class like:
public class Method implements Comparable<Method> {
public int compareTo(Method thatMethod) {
return Integer.compare(Integer.parseInt(this.cost), Integer.parseInt(thatMethod.getCost()));//if you need name then you could do this.cost.compareTo(thatMethod.getServiceType()); assuming serviceType can never be null
}
}
And then sort your list like:
Collections.sort(methods);
You can define new Comparator to define your sort criteria like this:
Comparator<Shipping> shippingComparator = new Comparator<Shipping>{
public int compare(Shipping obj1, Shipping obj2) {
//your rules for comparing Shipping1, Shipping 2 goes here
//return -1 when obj1 should be before obj2
//return 1 when obj1 should be after obj2
//return 0 when obj1 is equal to obj2 and relative position doesnt matter
}
Then use this comparator to sort your List:
ArrayList<Shipping> shippings;
//populate List
Collections.sort(shippings, shippingComparator );
You can first sort the methods field of each Shipping instance in your shippings list, then sort the shippings list by the first element of each instance's methods list:
for (Shipping shipping : shippings)
shipping.methods.sort((m1, m2) -> Integer.compare(m1.cost, m2.cost));
shippings.sort((s1, s2) ->
Integer.compare(s1.methods.get(0).cost, s2.methods.get(0).cost));
You might have to do a little extra work converting the costs to integers, but the overall idea is the same.
I would recommend that you read Java's ordering tutorial. Your requirements seem to indicate that you want to sort each Shipping instance by its Method, and somewhere else you want to sort a collection of Shipping instances that you want sorted alphabetically, but its not completely clear from what you've written.
In any case, this is straight forward to do once you read the tutorial. In summary, you can do this with a Comparator or by implementing Comparable, and simply invoking Collections.sort(...) on your dataset.
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.