As the title suggests, I have a list consisting of pairs of integers (int ai and int bi). I want to sort this list based on only upon int a, while preserving the pairwise relationship. I was wondering if there was an efficient way to do this with some of the standard libraries Java has. Thanks in advance!
Edit:
My exact implementation is an ArrayList<ArrayList<Integer>> in which each ArrayList<Integer> has exactly two integers (ai and bi). Sorry for any confusion.
Use the Collections sort() or Arrays sort() method which takes a Comparator and use a custom comparator which only inspects the first integer in the pair.
Something like this (roughly, depending on your exact types):
Collections.sort(myList, new Comparator<IntegerPair>() {
#Override public int compare(IntegerPair x, IntegerPair y) {
return x.first - y.first;
}
});
Since the sorting algorithms are stable (per the Javadocs) your list will be sorted per your description.
Implement http://docs.oracle.com/javase/6/docs/api/java/lang/Comparable.html for your integer pairs and use sort() from http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html
I would recommend to create a class that represents integer pair. This class should implement Comparable. The use sort() to sort it.
It may be a little safer to use the already-defined Integer compare:
Collections.sort(myList, new Comparator<IntegerPair>() {
#Override public int compare(IntegerPair x, IntegerPair y) {
return Integer.compare(x.first, y.first);
}
});
Related
I have a simple pair class and have created an array of them.
private static class Pair
{
private String l;
private String e;
}
I was wondering if it's possible to sort an array of pairs such as:
(a, de), (g, e), (dde, gh)
by just first element in the pair. Creating a result of: (a, de), (dde, gh), (g,e) I know this is possible in c++, but I'm new to Java and have been searching online for hours for a solution. I've read that you can use Comparator, but am still not sure how that really works. Any suggestions would be very much appreciated. Thanks!
Using an inline custom comparator:
Arrays.sort(pairArray, new Comparator<Pair>() {
#Override
public int compare(Pair p1, Pair p2) {
return p1.getL().compareTo(p2.getL());
}
});
The general approach would be:
Arrays.sort(myArray, new Comparator<Pair>() {
#Override
public int compare(Pair p1, Pair p2) {
return p1.l.compareTo(p2.l);
}
});
Java 8 makes it simpler with lambdas:
Arrays.sort(myArray, (p1, p2) -> p1.l.compareTo(p2.l));
In addition to Tim Biegeleisen's answer, there is one more option: make Pair implement Comparable interface:
private static class Pair implements Comparable<Pair>
{
private String l;
private String e;
int compareTo(Pair that) {
return this.l.compareTo(that.l);
}
}
List<Pair> pairList;
Collections.sort(pairList);
The choice between these two options depends on whether you want to modify Pair (Comparable requires it, Comparator does not), and whether you can have different possible orderings (Comparable allows to use only one ordering, Comparator allows to define as many orderings as you wish). Of course, you can also combine the approaches and implement default ordering in implementation of Comparable interface, but use also additional orderings with Comparator.
I have an ArrayList<ArrayList<String>> that is a list of couple of values:
John, 12.3
Marcus, 35.0
Sue, 11.4
How to sort the list by amount?
If in this case there is a better way than using an ArrayList of an ArrayList, please tell me and tell me then how to sort it. Thank you.
Instead I will recommend you to use a class and use class like comparable or comparator to sort.
Something like this:
class Person implements Comparable<Person> {
String name;
double amount;
Person(String n, double d) {
name = n;
amount = d;
}
public int compareTo(Person other) {
if (amount != other.amount)
return Double.compare(amount, other.amount);
return name.compareTo(other.name);
}
}
and this is easy to implement and understand.
Use a Comparator:
A comparison function, which imposes a total ordering on some
collection of objects. Comparators can be passed to a sort method
(such as Collections.sort or Arrays.sort) to allow precise control
over the sort order. Comparators can also be used to control the order
of certain data structures (such as sorted sets or sorted maps), or to
provide an ordering for collections of objects that don't have a
natural ordering.
It'd be great if you could add more information about why you are using those values then I am sure a better approach can be suggested.
I solved with this:
Collections.sort(data, new Comparator<ArrayList<String>>() {
#Override
public int compare(ArrayList<String> one, ArrayList<String> two) {
// Replacements for using Double.parseDouble(string) later
String value1 = one.get(1).replace(",", ".");
String value2 = two.get(1).replace(",", ".");
if (Double.parseDouble(value1) < Double.parseDouble(value2))
return -1;
else if (Double.parseDouble(value1) > Double.parseDouble(distanza2))
return 1;
else
return 0;
}
});
This is probably a simple question, but I have two arrays of approx 1000 elements each, they are called posXArray and posYArray. I want to sort posYArray numerically (lowest number first) but I want the elements of posXArray to have the same operation applied to them...
For example, if element [56] of posYArray is the smallest one , I want element [56] of posXArray to also be moved to [0].
How is this implemented in Java in an easy/good way?
Thank you very much for you help!
Since the arrays seem to contain X and Y coordinates, perhaps a better choice is to create a coordinate class containing both values, implement Comparable and just have a single array to sort using the built-in algorithms?
Create a class like:
public class XYPos implements Comparable<XYPos> {
int x;
int y;
#Override
public int compareTo(XYPos o) {
int res = this.y - o.y;
if(res == 0) {
res = this.x - o.x;
}
return res;
}
}
Then:
convert your 2 arrays into one array of XYPos
sort it
update your 2 original arrays with the values in the sorted array
Create an Integer[] idx of the same length and fill it with the numbers 0 to 999 (or whatever), then sort this array using a comparator that does
public int compare(Integer a, Integer b) {
return posYArray[a] - posYArray[b];
}
This will give you an array of indexes into the other arrays, i.e. the smallest Y value will be posYArray[idx[0]] and its corresponding X will be posXArray[idx[0]], etc. If you don't want to maintain the indirection you could re-order the original arrays by the idx values.
If you're doing this sort of thing regularly you may wish to look at fastutil which provides Collection and Comparator types that operate directly on primitive types such as int, avoiding the need to box and unbox Integers.
You could implement any sorting algorithm of your choice, do the comparation check on the first (posXArray) only, and then swap position of elements in both arrays at the same time.
How can I sort an array in Java/Android alphabetically?
After that I want to provide the ordered array to a ListView.
Arrays.sort() should do the trick
http://docs.oracle.com/javase/6/docs/api/java/util/Arrays.html
it can be done just using
Arrays.sort(myarray);
For more complex sorting see Comparator
Example:
Arrays.sort(some_array, new Comparator<SomeObject>() {
#Override
public int compare(SomeObject entry1, SomeObject entry2) {
return entry1.getSomeData().compareTo(entry2.getSomeData());
}
});
Objects that implement the Comparable interface (like Strings) have a natural ordering (as defined by its compareTo method) so you can just use Arrays.sort():
Arrays.sort(yourArrayOfComparables);
It will directly sort the array and will not make a copy.
If you want a more specific sort that isn't considered "natural" you can create a Comparator for that object:
Comparator<MyObject> comp = new Comparator<MyObject>() {
public int compare(MyObject obj1, MyObject obj2) {
//Code here
}
}
Arrays.sort(yourArrayOfObjects, comp);
The rules for Comparators and Comparables (where the first object is the object itself) is: return a negative if the first object is less than the second, positive for the other way round and 0 if they're equal.
How to sort an ArrayList<Long> in Java in decreasing order?
Here's one way for your list:
list.sort(null);
Collections.reverse(list);
Or you could implement your own Comparator to sort on and eliminate the reverse step:
list.sort((o1, o2) -> o2.compareTo(o1));
Or even more simply use Collections.reverseOrder() since you're only reversing:
list.sort(Collections.reverseOrder());
Comparator<Long> comparator = Collections.reverseOrder();
Collections.sort(arrayList, comparator);
You can use the following code which is given below;
Collections.sort(list, Collections.reverseOrder());
or if you are going to use custom comparator you can use as it is given below
Collections.sort(list, Collections.reverseOrder(new CustomComparator());
Where CustomComparator is a comparator class that compares the object which is present in the list.
Java 8
well doing this in java 8 is so much fun and easier
Collections.sort(variants,(a,b)->a.compareTo(b));
Collections.reverse(variants);
Lambda expressions rock here!!!
in case you needed a more than one line logic for comparing a and b you could write it like this
Collections.sort(variants,(a,b)->{
int result = a.compareTo(b);
return result;
});
Sort normally and use Collections.reverse();
For lamdas where your long value is somewhere in an object I recommend using:
.sorted((o1, o2) -> Long.compare(o1.getLong(), o2.getLong()))
or even better:
.sorted(Comparator.comparingLong(MyObject::getLong))
Sort, then reverse.
By using Collections.sort() with a comparator that provides the decreasing order.
See Javadoc for Collections.sort.
A more general approach to implement our own Comparator as below
Collections.sort(lst,new Comparator<Long>(){
public int compare(Long o1, Long o2) {
return o2.compareTo(o1);
}
});
The following approach will sort the list in descending order and also handles the 'null' values, just in case if you have any null values then Collections.sort() will throw NullPointerException
Collections.sort(list, new Comparator<Long>() {
public int compare(Long o1, Long o2) {
return o1==null?Integer.MAX_VALUE:o2==null?Integer.MIN_VALUE:o2.compareTo(o1);
}
});
You can also sort an ArrayList with a TreeSet instead of a comparator. Here's an example from a question I had before for an integer array. I'm using "numbers" as a placeholder name for the ArrayList.
import.java.util.*;
class MyClass{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
ArrayList<Integer> numbers = new ArrayList<Integer>();
TreeSet<Integer> ts = new TreeSet<Integer>(numbers);
numbers = new ArrayList<Integer>(ts);
System.out.println("\nThe numbers in ascending order are:");
for(int i=0; i<numbers.size(); i++)
System.out.print(numbers.get(i).intValue()+" ");
System.out.println("\nThe numbers in descending order are:");
for(int i=numbers.size()-1; i>=0; i--)
System.out.print(numbers.get(i).intValue()+" ");
}
}
So, There is something I would like to bring up which I think is important and I think that you should consider. runtime and memory. Say you have a list and want to sort it, well you can, there is a built in sort or you could develop your own. Then you say, want to reverse the list. That is the answer which is listed above.
If you are creating that list though, it might be good to use a different datastructure to store it and then just dump it into an array.
Heaps do just this. You filter in data, and it will handle everything, then you can pop everything off of the object and it would be sorted.
Another option would be to understand how maps work. A lot of times, a Map or HashMap as something things are called, have an underlying concept behind it.
For example.... you feed in a bunch of key-value pairs where the key is the long, and when you add all the elements, you can do: .keys and it would return to you a sorted list automatically.
It depends on how you process the data prior as to how i think you should continue with your sorting and subsequent reverses
Comparator's comparing method can be used to compare the objects and then method reversed() can be applied to reverse the order -
list.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(toList());
Using List.sort() and Comparator.comparingLong()
numberList.sort(Comparator.comparingLong(x -> -x));