Sorting of List<Object> - android

I need to sort the products by High to Low & Low to High of its Price.I have done Low to High by using following code.But dont know how to implement High To Low?
Your answer is more appreciated...
public static Comparator<Restaurant_Beam> strPriceFilterL2H = new Comparator<Restaurant_Beam>() {
#Override
public int compare(Restaurant_Beam lhs, Restaurant_Beam rhs) {
int CompareResult = 0;
if (Config.L2HFilterClicked == "L2H") {
CompareResult = (int) Math.round(Double.parseDouble(lhs.getIG_SALES_PRICE()) - Double.parseDouble(rhs.getIG_SALES_PRICE()));
}
//Used else if for H2L.But did not get it as perfect
else if (Config.L2HFilterClicked == "H2L") {
CompareResult = (int) Math.round(Double.parseDouble(lhs.getIG_SALES_PRICE()) + Double.parseDouble(rhs.getIG_SALES_PRICE()));
}
return CompareResult;
}
};

Change the second compare expression to this one:
CompareResult = (int) Math.round(Double.parseDouble(Double.parseDouble(rhs.getIG_SALES_PRICE()) - Double.parseDouble(lhs.getIG_SALES_PRICE()));
Also I'd like to point out a few things
consider doing Double comparison with epsilon
it's a good practice to check objects before comparing them
parsing each time you compare is really bad design. It would be better if you parse values somewhere in advance, consider changing your type. Currently it's not efficient.

Related

Android Run Time Array Size Efficiency

My tide prediction application uses 8 double arrays for tide height calculations. Literally every tide station in the United States requires these to have 37 elements, EXCEPT Anchorage, Alaska which requires 124 elements.
Here is a declaration example
final int NUM_C = 37; //all stations except anchorage use 37
//final int NUM_C = 124; //anchorage uses 124
double a[] = new double[NUM_C + 1];
Can I efficiently specify the array size at the start up of the app? I can determine which is needed. I don't want to burden the application with inefficiency for 99% + of the users to handle this one case. The difference is only about 3K bytes.
Why don't you instantiate the variable in the constructor? It gives you more freedom to do programatic manipulation.
public class Station {
double a[];
public Station(String location) {
if(location.equals("Anchorage")) {
a = new double[124];
} else {
a = new double[37];
}
}
}
As I understand the instantiation of the object fields in the constructor is the normal case, while the instantiation with the declaration is just an additional feature of Java.
As for the speed it does not make a difference, if you specify the size by a literal value, a constant or a variable. A more interesting question is, if you should use ArrayList instead of an array. See here.
public class Station {
ArrayList<Double> a;
public Station(String location) {
if(location.equals("Anchorage")) {
a = new ArrayList<>(124);
} else {
a = new ArrayList<>(37);
}
}
}
My choice would be ArrayList as it is more flexible. Eight times 124 is not a very large number anyway. No reason to worry about performance for this.

Is my target selection AI efficient?

quick question. I am developing a top-down 2d Platformer game with lots of enemies in the map (at least a hundred spawn at the start of each level). Each enemy uses an AI that searches the map for objects with a specified tag, sorts each object into a list based on their distance, then reacts to the object closest to them.
My code works, but the thing is, if the machine my game is running on is slow, then my game lags. I want to be able to port my game to Android and iOS with low end specs.
In pursuit of putting less strain on the CPU, is there a better way to write my AI?
Here is my code:
void Start () {
FoodTargets = new List<Transform>(); // my list
SelectedTarget = null; // the target the enemy reacts to
myTransform = transform;
AddAllFood ();
}
public void AddAllFood()
{
GameObject[] Foods = GameObject.FindGameObjectsWithTag("Object");
foreach (GameObject enemy in Foods)
AddTarget (enemy.transform);
}
public void AddTarget(Transform enemy)
{
if (enemy.GetComponent<ClassRatingScript>().classrating != 1) { // classrating is an attribute each enemy has that determines their identity (like if they are a plant, a herbivore or a carnivore)
FoodTargets.Add (enemy); // adds the object to the list
}
}
private void SortTargetsByDistance() // this is how I sort according to distance, is this the fastest and most efficient way to do this?
{
FoodTargets.Sort (delegate(Transform t1, Transform t2) {
return Vector3.Distance(t1.position, myTransform.position).CompareTo(Vector3.Distance(t2.position, myTransform.position));
});
}
private void TargetEnemy() // this is called every 4 frames
{
if (SelectedTarget == null) {
SortTargetsByDistance ();
SelectedTarget = FoodTargets [1];
}
else {
SortTargetsByDistance ();
SelectedTarget = FoodTargets [1];
}
}
if (optimizer <= 2) { // this is a variable that increments every frame and resets to 0 on the 3rd frame. Only every 3rd frame is the target enemy method is called.
optimizer++;
} else {
TargetEnemy ();
// the rest are attributes that the AI considers when reacting to their target
targetmass = SelectedTarget.GetComponent<MassScript> ().mass;
targetclass = SelectedTarget.GetComponent<ClassRatingScript> ().classrating;
mass = this.GetComponent<MassScript> ().mass;
classrating = this.GetComponent<ClassRatingScript> ().classrating;
distance = Vector3.Distance (transform.position, SelectedTarget.transform.position);
optimizer = 0;
}
Is there a more optimized way of doing this? Your help will be much appreciated. Thanks in advance!
I'm not awfully familiar with C# or Unity but I would look very carefully at what sorting algorithm your sorting method is using. If all you want is the closest Game Object, then sorting isn't necessary.
The fastest sorting algorithms, such as Quicksort, are O(n*log(n)). That is to say that the time it takes to sort a collection of n objects is bounded by some constant multiple of n*log(n). If you just want the k closest objects, where k << n, then you can perform k iterations of the Bubble Sort algorithm. This will have time-complexity O(k*n), which is much better then before.
However, if you only need the single closest object, then just find the closest object without sorting (pseudocode):
float smallestDistance = Inf;
object closestObject = null;
foreach object in objectsWithTag {
float d = distance(object, enemy);
if (d < smallestDistance) {
smallestDistance = d;
closestObject = object;
}
}
This extremely simple algorithm has time complexity O(n).

Android: Converting a set of functions into an equation

I am 99% sure that this cannot be done, however I thought I would ask to be certain.
I am attempting to create an application that calculates the required dice roll for an action in a popular tabletop war game.
The following is this calculation in Java
int x = ((WSattacker * 2) - WSdefender);
int y = (WSattacker - WSdefender);
String result;
// Calculation for a +5
if (x <= -1) {
result = "5+";
}
// Calculation for a +4
else if (x >= 0 && y <= 0) {
result = "4+";
}
// Calculation for a +3
else if (y > 0) {
result = "3+";
} else {
result = "Error";
}
return result;
Now my issue is that to avoid copywriter infringement I cannot mention the name of the game in my application, and probably cannot hard code the above calculation in the app.
This means that it is difficult to tell a potential user what the app will do.
The only solution I can think of is to make the application generic and allow the user to input the calculation required in the form of an equation.
An equation that I can place anonymously on a public board or similar.
Therefore my questions are as follows.
Is there another way of going about this?
If no, is it possible to condense the above code into a single expression/ equationi.e. one that removes the if and else statements
To answer question 2:
result = test_condition_1 ? result2_if_true : (test_condition_2 ? result2_if_true : test3_or_result2);
You can then build up 'compound' test conditions this way, and it's based upon ternary operators.
EDIT
Ternary operators are a short-hand way of writing if..then..else statments, and more information can be found in the wiki-link above. An example of its use is below, which you can compile and run:
public class TernaryTest {
public static void main(String [] args){
int x = 14;
int y = 5;
String result = ( x <= 10 ) ? "Less than 10" : "More than 10";
System.out.println("Result is: " + result);
}
}
Try running it and see the result as you change the value of x to understand how it works. Then it's possible to extend it to include and else by replacing the "more than 10" string.

Loop structure gives wrong result

I am trying to compare items out of my DB to the value of an EditText (user input). The answer can have multiple answers, seperated by a ','. I first put them into a stringarray and then compare them to the answer. The LevenshteinDistance checks if the answer is more or les good (http://en.wikipedia.org/wiki/Levenshtein_distance#Computing_Levenshtein_distance).
userAnswer = etUserAnswer.getText().toString().toLowerCase();
String[] answers = qAnswer.split(",");
for (String answer : answers) {
if (answer.equals(userAnswer)) {
Toast.makeText(getApplicationContext(), ("Answer Correct"),
Toast.LENGTH_SHORT).show();
tvMessage.setText("You smartass!");
} else {
Toast.makeText(getApplicationContext(), ("Wrong"),
Toast.LENGTH_SHORT).show();
points = points - 4;
String answerGood = answer.toLowerCase();
LevenshteinDistance lDistance = new LevenshteinDistance();
int comparisonCheck = lDistance.computeLevenshteinDistance(
userAnswer, answerGood);
if (comparisonCheck == 1) {
tvMessage.setText("Almost there, but not quite yet!");
} else if (comparisonCheck > 1) {
tvMessage.setText("Are you serious, totally wrong?!");
}
}
}
Suppose I am having the answers for a question in the DB as follows: tree,test,radio
I am having two problems:
1. When I type "radi" it gives me 'Almost there...' which is good. It should also give me this if I enter "tes", but instead it gives me the 'Are you serious,...' line. I guess it keeps comparing to the last one.
2. Every time I type in something which is not correct, I get -12 instead of -4. I suppose this is due to the fact I am having three answers and it loops three times.. but I don't know how I can make it count only once..
Anyone can help me on the way? Thanks!
Assuming you don't need to know the word which gives the least Levenshtein distance, you could modify your loop to find smallest distance only;
userAnswer = etUserAnswer.getText().toString().toLowerCase();
String[] answers = qAnswer.split(",");
LevenshteinDistance lDistance = new LevenshteinDistance();
int minDistance = lDistance.computeLevenshteinDistance(
userAnswer, answers[0].toLowerCase());
for (int i = 1; i < answers.length; ++i) {
minDistance = Math.min(minDistance, lDistance.computeLevenshteinDistance(
userAnswer, answers[i].toLowerCase()));
}
if (minDistance == 0) {
// Correct answer...
} else {
// Wrong answer...
points -= 4;
// etc etc...
}

Are dimen values cached?

Is there any performance gain over doing the following:
final int pixels = getResources.getDimensionPixelSize(R.dimen.pixels);
for (CustomView view: views) {
view.setPixelValue(pixels);
}
vs.
for (CustomView view: views) {
view.setPixelValue(getResources.getDimensionPixelSize(R.dimen.pixels));
}
Or are dimens values cached / the bytecode optimised / some other optimisation that makes this redundant?
Looking at Resources.getDimentionPixelSize() and deeper till AssetManager.loadResourceValue() which is native it's impossible to say. However, from Resources.getDimentionPixelSize() source it's possible to say the following:
public int getDimensionPixelSize(int id) throws NotFoundException {
synchronized (mAccessLock) {
TypedValue value = mTmpValue;
if (value == null) {
mTmpValue = value = new TypedValue();
}
getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelSize(
value.data, mMetrics);
}
throw new NotFoundException(
"Resource ID #0x" + Integer.toHexString(id) + " type #0x"
+ Integer.toHexString(value.type) + " is not valid");
}
}
It will lock resources by synchronized (mAccessLock) (read, if some other thread of you will try to access resources same moment - on of them will wait);
It will call some float math inside TypedValue.complexToDimensionPixelSize();
It will probably create TypedValue object;
It will do at least 5 method calls;
So, maybe it's cached somewhere in native, but even so, call will be definitely not free for you.
Here's some measurements I've done for this question (with only single thread accessing resources):
int pixels = 0;
Resources res = getResources();
long ms = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
pixels = res.getDimensionPixelSize(R.dimen.my_dimen);
}
Log.e(TAG, "Time " + (System.currentTimeMillis() - ms));
On S6 with Android Lollipop it gives about 816 ms, or 8160 nano-sec / call.
Finally, in your case (I believe you have maximum 10-20 iterations) it really doesn't matter in terms of performance. In more iterations and / or some concurrency in access to resources in might be significant.
Personally I would suggest to do it outside for better style and small but still speed improvement.

Categories

Resources