Related
I have this method to merge 2 sorted arrays into one sorted array:
public void merge(T[] a, int l1, int r1, T[] b, int l2, int r2, T[] c, int l3) {
while (l1 < r1 && l2 < r2) {
if (a[l1].compareTo(b[l2]) < 0) {
c[l3++] = a[l1++];
} else
c[l3++] = b[l2++];
}
while (l1 < r1)
c[l3++] = a[l1++];
while (l2 < r2)
c[l3++] = b[l2++];
}
But now I want to do it with 4 arrays at once.
I tried really long to come up with a solution, but wasn’t really successful. Does somebody have an idea how to do it?
There is a much simpler way using Java8 streams than doing this by hand:
combine all arrays into one stream (i've used 2 but you can use as many as you want to):
int[] arr1 = {1, 7, 10};
int[] arr2 = {1, 2, 4, 9};
Stream<int[]> ints = Stream.of(arr1, arr2);
then flatMap and sort them in a stream:
IntStream intStream = ints.flatMapToInt(Arrays::stream).sorted();
and when you print them you will see all the numbers sorted:
intStream.forEach(System.out::println);
1
1
2
4
7
9
10
combined in a function, it could look something like this:
public int[] merge(int[]... arrays) {
return Stream.of(arrays)
.flatMapToInt(Arrays::stream)
.sorted()
.toArray();
}
EDIT: The advantage of streams is, that you can further modify the values as you like. e.g. by leveraging the distinct function you can easily remove duplicates:
intStream = intStream.distinct();
intStream.forEach(System.out::println);
1
2
4
7
9
10
I've generalized the problem to "merging N sorted arrays into a single sorted array".
The code provided in the question utilizes generics. But it introduces a problem because arrays are not type-safe. In short, there's a substantial difference in their behavior: arrays are covariant and, on the other hand, generics are invariant. Due to that, compiler will not be abler to identify a problem when generics and arrays are mixed. It's a good practice to avoid usage of generic arrays.
Also, I've taken into account that it is clearly an algorithmic problem (therefore its audience broader than readers who have a deep insight in Java, which is required to grasp generic-based implementation) I've decided to create two flavors of solution one using arrays exclusively, another with generics and Collections framework.
Non-generic version
Below is the description of how to merge an arbitrary number of sorted arrays of primitives:
find the total number of elements and create a resulting array based on it;
define an array that will maintain a current position in each of the source arrays;
using a nested for loop for each position in the resulting array, pick the lowest value of all currently accessible values.
The time complexity of this algorithm is O(n * m) (where n - is the total number of elements in all arrays and m is the number of arrays).
The implementation might look like this:
public static int[] mergeNSorted(int[]... arrays) {
int[] result = new int[getTotalLength(arrays)];
int[] positions = new int[arrays.length]; // position for each array
for (int pos = 0; pos < result.length; pos++) {
int minCurVal = Integer.MAX_VALUE;
int curArr = 0;
for (int i = 0; i < arrays.length; i++) {
if (positions[i] < arrays[i].length && arrays[i][positions[i]] < minCurVal) {
minCurVal = arrays[i][positions[i]];
curArr = i;
}
}
result[pos] = minCurVal;
positions[curArr]++;
}
return result;
}
public static int getTotalLength(int[][] arrays) {
long totalLen = 0;
for (int[] arr : arrays) totalLen += arr.length;
if (totalLen > Integer.MAX_VALUE) throw new IllegalArgumentException("total length exceeded Integer.MAX_VALUE");
return (int) totalLen;
}
main() - demo
public static void main(String[] args) {
int[][] input =
{{1, 3}, {}, {2, 6, 7}, {10}, {4, 5, 8, 9}};
System.out.println(Arrays.toString(mergeNSorted(input)));
}
Output
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Generic version
In this version, input considered to be a list containing multiple lists of generic type T which expected to implement Comparable interface.
This solution enhances the array-based implementation provided above, reducing the overall time complexity to O(n * log m) (where n - is the total number of elements in all arrays and m is the number of arrays).
Instead of performing m iteration for each resulting element it maintains a PriorityQueue, which in this case represents a Min-Heap (i.e. when a head element is being retrieved from it, it'll have the lowest value of all the elements that are present in the queue).
Every element in queue wraps the value of a particular element retrieved from one of the given lists, as well the data regarding the source of this value (i.e. an index of the list and a position inside this list).
This wrapper over the element of the nested list can be represented by the class shown below.
public class ElementWrapper<V extends Comparable<V>> implements Comparable<ElementWrapper<V>> {
private V value;
private int listIndex;
private int position;
public ElementWrapper(V value, int listIndex, int position) {
this.value = value;
this.listIndex = listIndex;
this.position = position;
}
// getters
#Override
public int compareTo(ElementWrapper<V> o) {
return value.compareTo(o.getValue());
}
}
Note, that this class implements the of Comparable interface based on the value of wrapped list element.
The queue is being prepopulated with the first element of each non-empty list. And then until the queue is not empty, its lowest element is being removed and gets added to the resulting list. Also, if a list to which the latest element retrieved from the queue points, has more elements, the next of them will be added into the queue.
Note that both operations of adding a new element into the priority queue add() and removing its head element remove() according to the documentation has a cost of O(n) time (where n is the number of elements in the queue).
The same time complexity can be achieved by utilizing a TreeSet instead, but in practice PriorityQueue will perform better because a heap is easier to maintain than a red-black tree.
The code might look like this:
public static <T extends Comparable<T>> List<T> mergeNSorted(List<List<T>> lists) {
List<T> result = new ArrayList<>();
Queue<ElementWrapper<T>> queue = getInitializedQueue(lists);
while (!queue.isEmpty()) {
ElementWrapper<T> next = queue.remove();
result.add(next.getValue());
if (next.getPosition() + 1 < lists.get(next.getListIndex()).size()) {
queue.add(new ElementWrapper<>(lists.get(next.getListIndex()).get(next.getPosition() + 1),
next.getListIndex(),
next.getPosition() + 1));
}
}
return result;
}
public static <T extends Comparable<T>> Queue<ElementWrapper<T>> getInitializedQueue(List<List<T>> lists) {
Queue<ElementWrapper<T>> queue = new PriorityQueue<>();
for (int i = 0; i < lists.size(); i++) {
if (lists.get(i).isEmpty()) continue;
queue.add(new ElementWrapper<>(lists.get(i).get(0), i, 0));
}
return queue;
}
main() - demo
public static void main(String[] args) {
List<List<Integer>> genericInput =
List.of(List.of(1, 3), List.of(), List.of(2, 6, 7), List.of(10), List.of(4, 5, 8, 9));
System.out.println(mergeNSorted(genericInput));
}
Output
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I'm not a Java programmer so I'll just give Pythonesque pseudo-code.
First turn each non-emptyarray into a triplet:
(next_value, index, array)
Now put those into a priority queue sorted by next value.
while 0 < queue.size():
(next_value, index, array) = queue.poll()
answer.append(next_value)
if index+1 < array.length:
queue.add((array[index+1], index+1, array))
If you have k arrays, this will take O(log(k)) comparisons per element produced.
Sadly, Java does not seem to have anything corresponding to the swaptop method. I practice if one array has a run of values, using .peek() to get the top element then .swaptop(...) if you can will let you go through those runs with O(1) work per element.
This could also be an good example using List<String> in addition to int[]
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TestClass {
public static List<String> list(String... elems) {
return new ArrayList<>(Arrays.asList(elems));
}
public static List<String> mergedListSorted(List<String>... listsVarArgs) {
return Stream.of(listsVarArgs).flatMap(List::stream).sorted().collect(Collectors.toList());
}
#Test
public void sortedListsTest() {
// Sorted sub lists
List<String> AGMS = list("A", "G", "M", "S");
List<String> BHNT = list("B", "H", "N", "T");
List<String> CIOU = list("C", "I", "O", "U");
List<String> DJPV = list("D", "J", "P", "V");
List<String> EKQW = list("E", "K", "Q", "W");
List<String> FLRX = list("F", "L", "R", "X");
System.out.println(mergedListSorted(AGMS, BHNT, CIOU, DJPV, EKQW, FLRX));
System.out.println(mergedListSorted(BHNT, BHNT, CIOU, BHNT));
}
}
The according output of two examples:
[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
[B, B, B, C, H, H, H, I, N, N, N, O, T, T, T, U]
I want to sum up each i array and store it as an element of a new array.
I expect to get int[] sumUp={10,30}
What am I doing wrong?
My result is instead {0,10}
int[][] matrixOne= {{1,2,3,4},{10,20}};
int [] sumUp=new int[matrixOne.length];
int toSum=0;
for(int i=0;i<matrixOne.length;i++) {
sumUp[i]=toSum;
for(int j=0;j<matrixOne[i].length;j++) {
toSum+=matrixOne[i][j];
}
}
System.out.println(Arrays.toString(sumUp));
You're storing the result before you sum the numbers.
EDIT: forgot to reset the sum
toSum = 0;
for(int j=0;j<matrixOne[i].length;j++) {
toSum+=matrixOne[i][j];
}
sumUp[i]=toSum;
I would prefer a stream on the int[][] which you can map (and stream() to sum()) in one pass. Like,
int[][] matrixOne = { { 1, 2, 3, 4 }, { 10, 20 } };
int[] sumUp = Arrays.stream(matrixOne).mapToInt(x -> Arrays.stream(x).sum()).toArray();
System.out.println(Arrays.toString(sumUp));
Outputs (as expected)
[10, 30]
As the others are pointing out you are storing your sum in toSum not sumUp in your inner loop.
If you want to avoid these mistakes, and you are using Java 8, you could simply do something like:
int[][] matrixOne= {{1,2,3,4},{10,20}};
int [] sumUp=new int[matrixOne.length];
for(int i=0;i<matrixOne.length;i++) {
sumUp[i] = Arrays.stream(matrixOne[i]).sum();
}
You could even stream and map the outer array, but it becomes a bit more complicated.
public static int[] convertListToArray(List<Integer> listResult) {
int[] result = new int[listResult.size()];
int i= 0;
for (int num : listResult) {
result[i++] = num;
}
return result;
}
Is there an efficient way to convert List to array without iterating List explicitly ?
Maybe it is possible by using methods like:
Arrays.copyOf(int [] origin , int newLength );
System.arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
I know that there is a solution described here. However, I particularly interested in an efficient way of converting List<Integer> to int[]
Given the need to convert from Integer to int, I don't think you're going to find something more efficient than what you have, if I assume you're talking about runtime efficiency.
You might find converting to Integer[] first and then looping might be more efficient (below), but you might not, too. You'd have to test it in your specific scenario and see.
Here's that example:
int size = listResult.size();
int[] result = new int[size];
Integer[] temp = listResult.toArray(new Integer[size]);
for (int n = 0; n < size; ++n) {
result[n] = temp[n];
}
If efficiency is your primary concern, I think you can use your solution and make it more efficient by using an indexed for loop on the listResult if it is RandomAccess. However this makes the code much less readable, and you'd have to benchmark it for your use cases to see if it is more efficient.
public static int[] convertListToArray(List<Integer> listResult) {
int size = listResult.size();
int[] result = new int[size];
if (listResult instanceof RandomAccess)
{
for (int i = 0; i < size; i++)
{
result[i] = listResult.get(i);
}
}
else
{
int i = 0;
for (int num : listResult) {
result[i++] = num;
}
}
return result;
}
If you use Java 8 and would like to write less code you can use the Streams library.
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int[] array = list.stream().mapToInt(i -> i).toArray();
If you are open to using a third party library, you can Eclipse Collections as follows.
MutableList<Integer> list = Lists.mutable.with(1, 2, 3, 4, 5);
int[] array = list.collectInt(i -> i).toArray();
The following is slightly more code, but is the most efficient solution I could come up with using Eclipse Collections.
MutableList<Integer> list = Lists.mutable.with(1, 2, 3, 4, 5);
int[] array = new int[list.size()];
list.forEachWithIndex((each, index) -> array[index] = each);
If you need to use the java.util.List interface, the ListIterate utility class can be used from Eclipse Collections.
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int[] array = new int[list.size()];
ListIterate.forEachWithIndex(list, (each, index) -> array[index] = each);
The ListIterate utility will use different iteration code for RandomAccess lists and non-RandomAccess lists.
The most efficient thing to do would be to change the List<Integer> to a MutableIntList in Eclipse Collections or another library that has support for primitive collections.
Note: I am a committer for Eclipse Collections.
In Java 8:
int[] anArray = list.stream()
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.toArray();
There is efficient way you could do this Java. However, this could open room for someone to create the generic function (depend on demand).
Just like this sample i wrote, I suggest you do the same to the specific knowledge of your program.
// Generic function to convert set to list
public static <T> ArrayList<T> convertSetToList(Set<T> set)
{
// create an empty list
ArrayList<T> list = new ArrayList<>();
// push each element in the set into the list
for (T t : set)
list.add(t);
// return the list
return list;
}
Okay so I am using the JavaMail library and I am trying to fetch certain message numbers. I want to do it efficiently and not have to loop twice over something… Anyways my question to you is: How can I create an array that starts at index x and ends at index x - 11 without looping?
If you want to create and populate an array, you have basically three options:
Write the values explicitly: int[] nums = new int[] { 0, 1, 2, 3, 4, ... }
Use some form of for-loop: for (int i = 0; i < 10; i++) { nums[i] = i; }
Create it recursively:
int[] nums = new int[12];
nums = populate(0, x, nums);
private int[] populate(int index, int x, int[] nums) {
if (nums.length >= index) {
return nums;
} else {
nums[index] = x - index; // x-0 through x-11
return populate(index+1, x, nums);
}
}
Vanilla Java, without extra libraries and whatnot, doesn't support a map function which would allow you to specify a function that would somehow auto-generate your values.
Though, I really don't understand why you don't want to use a loop, especially for something trivial like this.
int[] myArray = new int[] {x, x-1, x-2, x-3, x-4, x-5, x-6, x-7, x-8, x-9, x-10, x-11};
Since JDK 8 it's possible to populate an array using streams instead of for loops.
For example, an array of numbers x through x-11 can be generated using IntStream.iterate() which applies the specified function to every previous element to obtain the next one, in this case decrement.
int x = 55;
int[] arrayOfNumbers = IntStream
.iterate(x, previousNumber -> --previousNumber)
.limit(11)
.toArray();
// Creates an array containing: [55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45]
Is there any EASY way to sort an array in descending order like how they have a sort in ascending order in the Arrays class?
Or do I have to stop being lazy and do this myself :[
You could use this to sort all kind of Objects
sort(T[] a, Comparator<? super T> c)
Arrays.sort(a, Collections.reverseOrder());
Arrays.sort() cannot be used directly to sort primitive arrays in descending order. If you try to call the Arrays.sort() method by passing reverse Comparator defined by Collections.reverseOrder() , it will throw the error
no suitable method found for sort(int[],comparator)
That will work fine with 'Array of Objects' such as Integer array but will not work with a primitive array such as int array.
The only way to sort a primitive array in descending order is, first sort the array in ascending order and then reverse the array in place. This is also true for two-dimensional primitive arrays.
for a list
Collections.sort(list, Collections.reverseOrder());
for an array
Arrays.sort(array, Collections.reverseOrder());
You can use this:
Arrays.sort(data, Collections.reverseOrder());
Collections.reverseOrder() returns a Comparator using the inverse natural order. You can get an inverted version of your own comparator using Collections.reverseOrder(myComparator).
an alternative could be (for numbers!!!)
multiply the Array by -1
sort
multiply once again with -1
Literally spoken:
array = -Arrays.sort(-array)
without explicit comparator:
Collections.sort(list, Collections.reverseOrder());
with explicit comparator:
Collections.sort(list, Collections.reverseOrder(new Comparator()));
It's not directly possible to reverse sort an array of primitives (i.e., int[] arr = {1, 2, 3};) using Arrays.sort() and Collections.reverseOrder() because those methods require reference types (Integer) instead of primitive types (int).
However, we can use Java 8 Stream to first box the array to sort in reverse order:
// an array of ints
int[] arr = {1, 2, 3, 4, 5, 6};
// an array of reverse sorted ints
int[] arrDesc = Arrays.stream(arr).boxed()
.sorted(Collections.reverseOrder())
.mapToInt(Integer::intValue)
.toArray();
System.out.println(Arrays.toString(arrDesc)); // outputs [6, 5, 4, 3, 2, 1]
First you need to sort your array using:
Collections.sort(myArray);
Then you need to reverse the order from ascending to descending using:
Collections.reverse(myArray);
Java 8:
Arrays.sort(list, comparator.reversed());
Update:
reversed() reverses the specified comparator. Usually, comparators order ascending, so this changes the order to descending.
For array which contains elements of primitives if there is org.apache.commons.lang(3) at disposal easy way to reverse array (after sorting it) is to use:
ArrayUtils.reverse(array);
When an array is a type of Integer class then you can use below:
Integer[] arr = {7, 10, 4, 3, 20, 15};
Arrays.sort(arr, Collections.reverseOrder());
When an array is a type of int data type then you can use below:
int[] arr = {7, 10, 4, 3, 20, 15};
int[] reverseArr = IntStream.rangeClosed(1, arr.length).map(i -> arr[arr.length-i]).toArray();
I don't know what your use case was, however in addition to other answers here another (lazy) option is to still sort in ascending order as you indicate but then iterate in reverse order instead.
For discussions above, here is an easy example to sort the primitive arrays in descending order.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] nums = { 5, 4, 1, 2, 9, 7, 3, 8, 6, 0 };
Arrays.sort(nums);
// reverse the array, just like dumping the array!
// swap(1st, 1st-last) <= 1st: 0, 1st-last: nums.length - 1
// swap(2nd, 2nd-last) <= 2nd: i++, 2nd-last: j--
// swap(3rd, 3rd-last) <= 3rd: i++, 3rd-last: j--
//
for (int i = 0, j = nums.length - 1, tmp; i < j; i++, j--) {
tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
// dump the array (for Java 4/5/6/7/8/9)
for (int i = 0; i < nums.length; i++) {
System.out.println("nums[" + i + "] = " + nums[i]);
}
}
}
Output:
nums[0] = 9
nums[1] = 8
nums[2] = 7
nums[3] = 6
nums[4] = 5
nums[5] = 4
nums[6] = 3
nums[7] = 2
nums[8] = 1
nums[9] = 0
Another solution is that if you're making use of the Comparable interface you can switch the output values which you had specified in your compareTo(Object bCompared).
For Example :
public int compareTo(freq arg0)
{
int ret=0;
if(this.magnitude>arg0.magnitude)
ret= 1;
else if (this.magnitude==arg0.magnitude)
ret= 0;
else if (this.magnitude<arg0.magnitude)
ret= -1;
return ret;
}
Where magnitude is an attribute with datatype double in my program. This was sorting my defined class freq in reverse order by it's magnitude. So in order to correct that, you switch the values returned by the < and >. This gives you the following :
public int compareTo(freq arg0)
{
int ret=0;
if(this.magnitude>arg0.magnitude)
ret= -1;
else if (this.magnitude==arg0.magnitude)
ret= 0;
else if (this.magnitude<arg0.magnitude)
ret= 1;
return ret;
}
To make use of this compareTo, we simply call Arrays.sort(mFreq) which will give you the sorted array freq [] mFreq.
The beauty (in my opinion) of this solution is that it can be used to sort user defined classes, and even more than that sort them by a specific attribute. If implementation of a Comparable interface sounds daunting to you, I'd encourage you not to think that way, it actually isn't. This link on how to implement comparable made things much easier for me. Hoping persons can make use of this solution, and that your joy will even be comparable to mine.
For 2D arrays to sort in descending order you can just flip the positions of the parameters
int[][] array= {
{1, 5},
{13, 1},
{12, 100},
{12, 85}
};
Arrays.sort(array, (a, b) -> Integer.compare(a[1], b[1])); // for ascending order
Arrays.sort(array, (b, a) -> Integer.compare(a[1], b[1])); // for descending order
Output for descending
12, 100
12, 85
1, 5
13, 1
You could use stream operations (Collections.stream()) with Comparator.reverseOrder().
For example, say you have this collection:
List<String> items = new ArrayList<>();
items.add("item01");
items.add("item02");
items.add("item03");
items.add("item04");
items.add("item04");
To print the items in their "natural" order you could use the sorted() method (or leave it out and get the same result):
items.stream()
.sorted()
.forEach(item -> System.out.println(item));
Or to print them in descending (reverse) order, you could use the sorted method that takes a Comparator and reverse the order:
items.stream()
.sorted(Comparator.reverseOrder())
.forEach(item -> System.out.println(item));
Note this requires the collection to have implemented Comparable (as do Integer, String, etc.).
There is a lot of mess going on here - people suggest solutions for non-primitive values, try to implement some sorting algos from the ground, give solutions involving additional libraries, showing off some hacky ones etc. The answer to the original question is 50/50. For those who just want to copy/paste:
// our initial int[] array containing primitives
int[] arrOfPrimitives = new int[]{1,2,3,4,5,6};
// we have to convert it into array of Objects, using java's boxing
Integer[] arrOfObjects = new Integer[arrOfPrimitives.length];
for (int i = 0; i < arrOfPrimitives.length; i++)
arrOfObjects[i] = new Integer(arrOfPrimitives[i]);
// now when we have an array of Objects we can use that nice built-in method
Arrays.sort(arrOfObjects, Collections.reverseOrder());
arrOfObjects is {6,5,4,3,2,1} now. If you have an array of something other than ints - use the corresponding object instead of Integer.
Simple method to sort an int array descending:
private static int[] descendingArray(int[] array) {
Arrays.sort(array);
int[] descArray = new int[array.length];
for(int i=0; i<array.length; i++) {
descArray[i] = array[(array.length-1)-i];
}
return descArray;
}
Adding my answer in here for a couple of different scenarios
For an Array
Arrays.sort(a, Comparator.reverseOrder());
FWIW Lists
Lists.reverse(a);
Any and all Collections
Collections.reverse(a);
I know that this is a quite old thread, but here is an updated version for Integers and Java 8:
Arrays.sort(array, (o1, o2) -> o2 - o1);
Note that it is "o1 - o2" for the normal ascending order (or Comparator.comparingInt()).
This also works for any other kinds of Objects. Say:
Arrays.sort(array, (o1, o2) -> o2.getValue() - o1.getValue());
This worked for me:
package doublearraysort;
import java.util.Arrays;
import java.util.Collections;
public class Gpa {
public static void main(String[] args) {
// initializing unsorted double array
Double[] dArr = new Double[] {
new Double(3.2),
new Double(1.2),
new Double(4.7),
new Double(3.3),
new Double(4.6),
};
// print all the elements available in list
for (double number : dArr) {
System.out.println("GPA = " + number);
}
// sorting the array
Arrays.sort(dArr, Collections.reverseOrder());
// print all the elements available in list again
System.out.println("The sorted GPA Scores are:");
for (double number : dArr) {
System.out.println("GPA = " + number);
}
}
}
Output:
GPA = 3.2
GPA = 1.2
GPA = 4.7
GPA = 3.3
GPA = 4.6
The sorted GPA Scores are:
GPA = 4.7
GPA = 4.6
GPA = 3.3
GPA = 3.2
GPA = 1.2
public double[] sortArrayAlgorithm(double[] array) { //sort in descending order
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[i] >= array[j]) {
double x = array[i];
array[i] = array[j];
array[j] = x;
}
}
}
return array;
}
just use this method to sort an array of type double in descending order, you can use it to sort arrays of any other types(like int, float, and etc) just by changing the "return type", the "argument type" and the variable "x" type to the corresponding type. you can also change ">=" to "<=" in the if condition to make the order ascending.
Another way with Comparator
import java.util.Arrays;
import java.util.Comparator;
...
Integer[] aInt = {6,2,3,4,1,5,7,8,9,10};
Arrays.sort(aInt, Comparator.reverseOrder() );
It's good sometimes we practice over an example, here is a full one:
sortdesc.java
import java.util.Arrays;
import java.util.Collections;
class sortdesc{
public static void main(String[] args){
// int Array
Integer[] intArray=new Integer[]{
new Integer(15),
new Integer(9),
new Integer(16),
new Integer(2),
new Integer(30)};
// Sorting int Array in descending order
Arrays.sort(intArray,Collections.reverseOrder());
// Displaying elements of int Array
System.out.println("Int Array Elements in reverse order:");
for(int i=0;i<intArray.length;i++)
System.out.println(intArray[i]);
// String Array
String[] stringArray=new String[]{"FF","PP","AA","OO","DD"};
// Sorting String Array in descending order
Arrays.sort(stringArray,Collections.reverseOrder());
// Displaying elements of String Array
System.out.println("String Array Elements in reverse order:");
for(int i=0;i<stringArray.length;i++)
System.out.println(stringArray[i]);}}
compiling it...
javac sortdec.java
calling it...
java sortdesc
OUTPUT
Int Array Elements in reverse order:
30
16
15
9
2
String Array Elements in reverse order:
PP
OO
FF
DD
AA
If you want to try an alphanumeric array...
//replace this line:
String[] stringArray=new String[]{"FF","PP","AA","OO","DD"};
//with this:
String[] stringArray=new String[]{"10FF","20AA","50AA"};
you gonna get the OUTPUT as follow:
50AA
20AA
10FF
source
There is a way that might be a little bit longer, but it works fine. This is a method to sort an int array descendingly.
Hope that this will help someone ,,, some day:
public static int[] sortArray (int[] array) {
int [] sortedArray = new int[array.length];
for (int i = 0; i < sortedArray.length; i++) {
sortedArray[i] = array[i];
}
boolean flag = true;
int temp;
while (flag) {
flag = false;
for (int i = 0; i < sortedArray.length - 1; i++) {
if(sortedArray[i] < sortedArray[i+1]) {
temp = sortedArray[i];
sortedArray[i] = sortedArray[i+1];
sortedArray[i+1] = temp;
flag = true;
}
}
}
return sortedArray;
}
I had the below working solution
public static int[] sortArrayDesc(int[] intArray){
Arrays.sort(intArray); //sort intArray in Asc order
int[] sortedArray = new int[intArray.length]; //this array will hold the sorted values
int indexSortedArray = 0;
for(int i=intArray.length-1 ; i >= 0 ; i--){ //insert to sortedArray in reverse order
sortedArray[indexSortedArray ++] = intArray [i];
}
return sortedArray;
}
Here is how I sorted a primitive type int array.
int[] intArr = new int[] {9,4,1,7};
Arrays.sort(nums);
Collections.reverse(Arrays.asList(nums));
Result:
[1, 4, 7, 9]
I know many answers are here, but still thinks , none of them tried using core java.
And using collection api , you will end up wasting so much memory and reseduals.
here is a try with pure core concepts , and yes this may be better way if you are more concerned about memory footprints.
int[] elements = new int [] {10,999,999,-58,548,145,255,889,1,1,4,5555,0,-1,-52};
//int[] elements = null;
if(elements != null && elements.length >1)
{
int max = 0, index = 0;
for(int i =0;i<elements.length;i++)//find out what is Max
{
if(elements[i] > max)
{
max = elements[i];
index = i;
}
}
elements[index] = elements[0];//Swap the places
elements[0] = max;
for(int i =0;i < elements.length;i++)//loop over element
{
for(int j = i+1;j < elements.length;j++)//loop to compare the elements
{
if(elements[j] > elements[i])
{
max = elements[j];
elements[j] = elements[i];
elements[i] = max;
}
}
}
}//i ended up using three loops and 2 extra variables
System.out.println(Arrays.toString(elements));//if null it will print null
// still love to learn more, please advise if we can do it better.
Love to learn from you too !