Hi am trying to draw polygons on the map depending on the shortest distance.
i have created the array list called distancearray.
but i want to create a new array list called shortdistance, this array list must have the same values in the distancearray but it must be shorted in assending order depending on the distance.
can any one help me to create this shortdistance array. Thank you.
String array[][]=dbhand.collecting(getIntent().getExtras().getString("temple_type"), Integer.parseInt(getIntent().getExtras().getString("notemples")));
for(int i=0;i<array.length;i++){
displaymarkers(Double.parseDouble(array[i][0]), Double.parseDouble(array[i][1]), array[i][2]);
}
for(int i=0;i<array.length;i++){
double Distance = calculate_distance(SEATTLE_LAT, SEATTLE_LNG, Double.parseDouble(array[i][0]), Double.parseDouble(array[i][1]));
double[][] distancearray = new double[array.length][3];
distancearray[i][0]=Double.parseDouble(array[i][0]);
distancearray[i][1]=Double.parseDouble(array[i][1]);
distancearray[i][2]=Distance;
}
double [][] shortdistance = new double [array.length][3];
Draw Polygon Function
private void drawpolygon(String array[][]) {
int lengh = array.length;
if(lengh==2){
mMap.addPolygon(new PolygonOptions()
//.add(new LatLng(9.662502, 80.010239), new LatLng(9.670931, 80.013201), new LatLng(9.663216, 80.01333))
.add(new LatLng(9.6632139, 80.0133258))
.add(new LatLng(Double.parseDouble(array[0][0]), Double.parseDouble(array[0][1])))
.add(new LatLng(Double.parseDouble(array[1][0]), Double.parseDouble(array[1][1])))
.fillColor(Color.GRAY));
}
Just call Arrays.sort() against your array and specify a comparator that looks at the distance.
You are going to have difficulty sorting your arrays as-is because you currently store your data in parallel arrays:
distancearray[i][0]=Double.parseDouble(array[i][0]);
distancearray[i][1]=Double.parseDouble(array[i][2]);
distancearray[i][3]=Distance;
You can sort distancearray[n] but that will give you nonsense results. Instead what you should do is create a small class that implements Comparable (comparing based on distance) that holds your three values, then work with an array of those classes:
class DistanceInfo implements Comparable<DistanceInfo> {
public double a;
public double b;
public double distance;
public DistanceInfo (double a, double b, double distance) {
this.a = a;
this.b = b;
this.distance = distance;
}
#Override public int compareTo (DistanceInfo d) {
return Double.compare(distance, d.distance);
}
}
// then:
DistanceInfo[] distancearray = new DistanceInfo[array.length];
// and you can load it using the constructor:
for (int i = 0; i < array.length) {
double a = Double.parseDouble(array[i][0]);
double b = Double.parseDouble(array[i][1]);
distancearray[i] = new DistanceInfo(a, b, Distance);
}
(The fields can be made final if you wish to specify that they cannot be modified after construction.)
Now, Arrays.sort() will sort distancearray based on distance:
Arrays.sort(distancearray, null);
You could also use an ArrayList<DistanceInfo> instead, the idea is the same except you sort with Collections.sort().
In general, for this reason (among others) it is usually better to use a class to store all information about an object as opposed to parallel arrays.
As an aside, you may want to consider using this class for array as well, it will simplify your code a bit (you can modify displaymarkers to take a DistanceInfo, and you can also avoid parsing the same double more than once).
Related
I'm looking for simple way to build a Priority Queue in Java. I've built an ArrayList<Pair>, and each Pair instance contains an X and Y values.
class Pair {
private final Float xVal;
private final Float yVal;
public Pair(Float aXVal, Float aYVal) {
xVal = aXVal;
yVal = aYVal;
}
public float getX() {
return xVal;
}
public float getY() {
return yVal;
}
}
My ArrayList looks like:
ArrayList<Pair> listOfPoints;
Using the ArrayList listOfPoints, I wanted to build two priority queues:
One that is sorted on the x Values from low to high.
One that is sorted on the y Values form low to high.
I was looking for a simple way to do this using Lambda expressions.
I did look at this question on Stack Overflow, and I found this code:
PriorityQueue<String> pq=
new PriorityQueue<String>(5,(a,b) -> a.length() - b.length());
I think this is close to what I want.
I was trying to implement the following:
PriorityQueue<Pair> xSorted = new PriorityQueue<Pair>(numOfPoints, (x1,x2) -> Need Help Here);
How do I access Pair in order to have it compare x1 and x2?
Note, that nummberOfPoints I was setting to the length of ArrayList<Pair> listOfPoints.
For the natural (ascending) order based on xVal:
PriorityQueue<Pair> pq= new PriorityQueue<>(Comparator.comparingDouble(Pair::getX));
For the reversed (descending) order based on xVal:
PriorityQueue<Pair> pq= new PriorityQueue<>(Comparator.comparingDouble(Pair::getX).reversed());
You can use the same approach for yVal or any other comparable field, by using Comparator API.
You can also use lambda like this if you don't want Pair class to implement Comparator interface
PriorityQueue<Pair> queue = new PriorityQueue<>(5, (p1, p2) -> Float.compare(p1.getX(), p2.getX()));
For reverse order:
PriorityQueue<Pair> queue = new PriorityQueue<>(5, (p1, p2) -> Float.compare(p2.getX(), p1.getX()));
If you prefer your comparison logic in a static factory method or utility function, you can use something like this:
PriorityQueue<Pair> queue = new PriorityQueue<>(NodeUtil::customCompare);
public static int customCompare(Pair p1, Pair p2) {
return Float.compare(p1.getX(), p2.getX());
}
I am having a hard time understanding the right syntax to sort Maps which values aren't simply one type, but can be nested again.
I'll try to come up with a fitting example here:
Let's make a random class for that first:
class NestedFoo{
int valA;
int valB;
String textA;
public NestedFoo(int a, int b, String t){
this.valA = a;
this.valB = b;
this.textA = t;
}
}
Alright, that is our class.
Here comes the list:
HashMap<Integer, ArrayList<NestedFoo>> sortmePlz = new HashMap<>();
Let's create 3 entries to start with, that should show sorting works already.
ArrayList<NestedFoo> l1 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,2,"a");
n3 = new NestedFoo(1,4,"c");
l1.add(n1);
l1.add(n2);
l1.add(n3);
ArrayList<NestedFoo> l2 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,2,"a");
n3 = new NestedFoo(2,2,"b");
n4 = new NestedFoo(1,4,"c");
l2.add(n1);
l2.add(n2);
l2.add(n3);
l2.add(n4);
ArrayList<NestedFoo> l3 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,3,"b");
n3 = new NestedFoo(2,2,"b");
n4 = new NestedFoo(5,4,"c");
l3.add(n1);
l3.add(n2);
l3.add(n3);
l3.add(n4);
Sweet, now put them in our Map.
sortmePlz.put(5,l1);
sortmePlz.put(2,l2);
sortmePlz.put(1,l3);
What I want now, is to sort the Entire Map first by its Keys, so the order should be l3 l2 l1.
Then, I want the lists inside each key to be sorted by the following Order:
intA,intB,text (all ascending)
I have no idea how to do this. Especially not since Java 8 with all those lambdas, I tried to read on the subject but feel overwhelmed by the code there.
Thanks in advance!
I hope the code has no syntatical errors, I made it up on the go
You can use TreeSet instead of regular HashMap and your values will be automatically sorted by key:
Map<Integer, ArrayList<NestedFoo>> sortmePlz = new TreeMap<>();
Second step I'm a little confused.
to be sorted by the following Order: intA,intB,text (all ascending)
I suppose you want to sort the list by comparing first the intA values, then if they are equal compare by intB and so on. If I understand you correctly you can use Comparator with comparing and thenComparing.
sortmePlz.values().forEach(list -> list
.sort(Comparator.comparing(NestedFoo::getValA)
.thenComparing(NestedFoo::getValB)
.thenComparing(NestedFoo::getTextA)));
I'm sure there are way of doing it with lambda but it is not actually required. See answer from Schidu Luca for a lambda like solution.
Keep reading if you want an 'old school solution'.
You cannot sort a map. It does not make sense because there is no notion of order in a map. Now, there are some map objects that store the key in a sorted way (like the TreeMap).
You can order a list. In your case, makes the class NestedFoo comparable (https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html). Then you can invoke the method Collections.sort (https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-) on your lists.
Use TreeMap instead of HashMap, it solves the 1st problem: ordering entries by key.
After getting the needed list from the Map, you can sort the ArrayList by valA, valB, text:
l1.sort(
Comparator.comparing(NestedFoo::getValA).thenComparing(NestedFoo::getValB).thenComparing(NestedFoo::getTextA)
);
And change your NestedFoo class definition like this:
class NestedFoo {
int valA;
int valB;
String textA;
public NestedFoo(int a, int b, String t) {
this.valA = a;
this.valB = b;
this.textA = t;
}
public int getValA() {
return valA;
}
public void setValA(int valA) {
this.valA = valA;
}
public int getValB() {
return valB;
}
public void setValB(int valB) {
this.valB = valB;
}
public String getTextA() {
return textA;
}
public void setTextA(String textA) {
this.textA = textA;
}
}
When using treemap for sorting keep in mind that treemap uses compareTo instead of equals for sorting and to find duplicity. compareTo should be incosistent with equals and hashcode when implemented for any object which will be used as key. You can look for a detailed example on this link https://codingninjaonline.com/2017/09/29/unexpected-results-for-treemap-with-inconsistent-compareto-and-equals/
I am writing an program for an engineering application that needs a large number of 1x3 arrays to store coefficients for a very long rigid body mechanics equation. As such, I have about 90 arrays that need to conform to a very specific and longstanding engineering syntax. Imagine I have the following:
double[] a = {0.0, 0.0, 0.0}
double[] b = {0.0, 0.0, 0.0}
double[] c = {0.0, 0.0, 0.0}
etc.......
double[] zz = {0.0, 0.0, 0.0}
You can see that this is quite unwieldy.
As I understand from reading this discussion on primitive declaration in Java, there is no way to initialize a list of variables to the same value. For instance, in the following code:
double[] a, b, c, ...... zy, zz = new double[3];
However, this only initializes array zz, is there really no better way to initialize a large number of arrays than with the first method in this post? Is there a better overall approach to storing a large number of arrays that need to be descriptively named? I would like to be able to store the data in a two dimensional array but unfortunately these values need to be descriptive.
For reference, I need to initialize these arrays because the data that is being assigned to them originates from a list that is passed to the object instance when it is constructed. I can't assign a value to an uninitialized variable or I get a NullPointerException. For example:
a[index] = listWithDataIWantToAssign.get(listIndex);
returns a NullPointerException when using the second (invalid) method of initialization mentioned above.
If you have to work with a large ammount of arrays it's preferable to use a double array instead of excessive ammount of variables. I recommand you to create a simple double array double[][] myArray = new double[90][3]
Is there a better overall approach to storing a large number of arrays that need to be descriptively named?
if all variables are named it will be difficult to not type all names. But instead of name variables why not name values it by ints using static names ?
you can create a class keeping all names like that :
public static class VariablesNames{
private static int counter = 0;
public static final int NAME_1 = counter++;
public static final int NAME_2 = counter++;
public static final int NAME_3 = counter++;
...
}
Then use these variables in your code
double val = myArray[VariablesNames.NAME_1][0];
is there really no better way to initialize a large number of arrays than with the first method in this post?
If you have a really large ammout of arrays, it's not really usefull to initialise all arrays at the beginning. You can lazy load the array and use getter an setter on it
double[][] myArray = new double[90][];
public void init(int position){
if(myArray[position] == null){
myArray[position] = new double[3];
}
}
public double[] get(int position) {
init(position);
return myArray[position];
}
public void set(int position, List<Double> listWithDataIWantToAssign){
init(position);
for (int i = 0; i < 3; i++) {
myArray[position][i] = listWithDataIWantToAssign.get(i);
}
}
Then use these methods in your code
set(VariablesNames.NAME_2, listWithDataIWantToAssign);
double val = get(VariablesNames.NAME_2)[1];
The following code will return a 2d array of 'double' primitives, with size [N][3]. N is the number of arrays, or 90 in your example, and 3 the three double numbers in each array:
public static double[][] initDoubleArrays (int N) {
double[][] doublesArray = new double[N][3];
// the doubles will be set to 0.0 by default.
return doublesArray;
}
Alternatively, the following code will return a list where each element is a Double[] array with three Double objects
public static List<Double[]> initArrays (int nArrays) {
List<Double[]> arrays = new ArrayList<Double[]>(nArrays);
for (int i = 0; i<nArrays; i++) {
Double[] doubles = { 0.0, 0.0, 0.0 };
arrays.add(doubles);
}
return arrays;
}
Since a List couldn't be the best approach you should consider creating your own Factory, improved a little by maybe playing with the size, and the initial value...
like:
public class MyClass implements IArrayFactory {
public static void main(String[] args) {
MyClass foo = new MyClass();
List<List<Double>> l = new ArrayList<>();
for (int i = 0; i < 10; i++) {
l.add(foo.getListDouble(3, 0.0));
}
System.out.println(l);
}
#Override
public List<Double> getListDouble(int size, double initVal) {
Double[] d = new Double[size];
Arrays.fill(d, initVal);
return Arrays.asList(d);
}
}
interface IArrayFactory {
List<Double> getListDouble(int size, double initVal);
}
Hi I'm trying to sort an object based on a value of that object. Originally I used TreeMap which did the sorting but there were some non-unique keys which were removed so that didn't work. I googled around and came across Guava MultiMap. But how do I actually use this to sort the values?
Basically I'm trying to sort budget information based on the diffYTD_percentage value. Thanks!
Multimap<Double, BudgetInformation> multiMap = ArrayListMultimap.create();
for (Budget budget : budgets) {
BudgetInformation budgetInfo = getBudget(budget.getId());
double actualToDate = budgetInfo.getActualToDate();
double budgetToDate = budgetInfo.getTotalBudgetToDate();
double diffYTD_value = budgetToDate - actualToDate;
double diffYTD_percentage_value = 0.0;
if (budgetToDate != 0.0) {
double fraction = actualToDate / budgetToDate;
fraction = fraction - 1;
diffYTD_percentage_value = fraction * 100;
}
multiMap.put(diffYTD_percentage_value, budgetInfo);
}
Iterator<BudgetInformation> budgetIterator = multiMap.values().iterator();
Using Tree in order to sort collection is wrong approach. In Java there are dedicated utility methods to sort list, Collections.sort(List<T extends Comparable<? super T>> list) and Collections.sort(List<T> list, Comparator<? super T> c). The first is used to sort list where elements have natural ordering (basically implement Comparable interface), the later is used in cases like your own, when you need to sort elements using custom ordering.
So, basically what you need to do is to create Comparator that will compare two BusinessInfo instances based on diffYTD_percentage_value and call Collections.sort with this comparator.
Comparator<BudgetInformation> budgetInfoCmp = new Comparator<BudgetInformation>() {
private double getDiffYTDPercentage(BudgetInformation budgetInfo) {
double actualToDate = budgetInfo.getActualToDate();
double budgetToDate = budgetInfo.getTotalBudgetToDate();
double diffYTDValue = budgetToDate - actualToDate;
double diffYTDPercentageValue = 0.0;
if (budgetToDate != 0.0) {
double fraction = actualToDate / budgetToDate;
fraction = fraction - 1;
diffYTDPercentageValue = fraction * 100;
}
return diffYTDPercentageValue;
}
#Override
public int compare(BudgetInformation o1, BudgetInformation o2) {
return Double.compare(getDiffYTDPercentage(o1), getDiffYTDPercentage(o2));
}
};
List<BudgetInformation> budgetInformationsToSort = getBudgetInformations();
Collections.sort(budgetInformationsToSort, budgetInfoCmp);
Also try to avoid using underscore in variable naming, as under Java naming convention variable names should be in camel case.
How about using TreeMultiMap? It doesnt support duplicate key-value pair. But duplicate keys are fine.
Hey, I need to sort an array list of class house by a float field in a certain range. This is my code for the selection sort:
Basically sortPrice copies the stuff in this list into a new one selecting only the values in that range, then it does a selection sort in that array list. The arraylist (x) in sortPrice is unsorted an needs to be copied because what x references cannot be altered.
public ArrayList<House> sortPrice(ArrayList<House> x,float y, float z){
ArrayList<House> xcopy = new ArrayList<House>();
for(int i = 0; i<x.size(); i++){
if(x.get(i).myPriceIsLessThanOrEqualTo(z) && x.get(i).myPriceIsGreaterThanOrEqualTo(y)){
xcopy.add(x.get(i));
}
}
ArrayList<House> price= new ArrayList<House>();
while(xcopy.size()>0){
House min = xcopy.get(0);
for(int i = 1; i < xcopy.size();i++){
House current = xcopy.get(i);
if (current.myPriceIsGreaterThanOrEqualTo(min.getPrice())){
min = current;
}
}
price.add(min);
xcopy.remove(min);
}
return price;
}
Here is what the house class looks like:
public class House {
private int numBedRs;
private int sqft;
private float numBathRs;
private float price;
private static int idNumOfMostRecentHouse = 0;
private int id;
public House(int bed,int ft, float bath, float price){
sqft = ft;
numBathRs = bath;
numBedRs = bed;
this.price = price;
idNumOfMostRecentHouse++;
id = idNumOfMostRecentHouse;
}
public boolean myPriceIsLessThanOrEqualTo(float y){
if(Math.abs(price - y)<0.000001){
return true;
}
return false;
}
public boolean myPriceIsGreaterThanOrEqualTo(float b){
if(Math.abs(b-price)>0.0000001){
return true;
}
return false;
}
When i call looking for houses in range 260000.50 to 300000 I only get houses that are at the top of the range even though I have a lower value at 270000. Can someone help?
You should use rounded double type.
DecimalFormat p= new DecimalFormat( "#0.00" );
double price = 123.00001;
price = new Double(p.format(price)).doubleValue();
Your method name indicates it sorts the data, the method also filters. You need to change the name. Actually there are a number of variables in this code which need their names change to better reflect what they contain.
You need to replace the for loops with for-each loops. That will simply and make the code clearer. You would also no longer need the while() statement.
I would also refactor the mypriceis... methods into a single ispriceinrange method.
Alternatively I'd look at the comparator interface and look at introducing it as a way to sort you data without having to hand code a loop.
Just took a second look. You do actually sort in the second loop, but that some ugly code and probably won't perform well to boot. Definitely go look at comparator and Collections.sort() methods. Save yourself a world of pain.
The best data structure for this problem would be a NavigableMap<Float,List<House>> (such as a TreeMap), which supports a subMap operation:
SortedMap<K,V> subMap(K fromKey, K toKey) : Returns a view of the portion of this map whose keys range from fromKey, inclusive, to toKey, exclusive.
There is also an overload that allows you to set inclusive bounds.
Here's a demonstration:
NavigableMap<Integer,String> nmap = new TreeMap<Integer,String>();
nmap.put(5, "Five");
nmap.put(1, "One");
nmap.put(7, "Seven");
nmap.put(3, "Three");
System.out.println(nmap.subMap(2, 6));
// prints {3=Three, 5=Five}
For your case, you'd want to either make House implementsComparable<House>, or define your own custom Comparator<House>. You'd then let TreeMap do the sorting for you, and don't have to deal with selection sort (which, at O(N^2), is far from optimal).
If you're stuck with the specification that you're given, then I'd suggest breaking apart the logic into helper methods like these:
List<House> filterInRange(List<House> houses, float low, float high) {
List<House> ret = new ArrayList<House>();
for (House h : houses) {
if (isInRange(h.getPrice(), low, high)) {
ret.add(h);
}
}
return ret;
}
static boolean isInRange(float v, float low, float high) { ...DIY... }
void selectionSort(List<House> houses) { ...Wikipedia... }
Then to get a sorted List<House> in a specified price range, invoke filterInRange and then selectionSort the returned list.
See also
Java language guide/for-each