I have a multidimensional array with double values that I would like to sort..
//declare array
standingsB = new Double[10][2];
//populate array from the temparray created during read from file
arryLgt = 0;
for (int row = 0; row < standingsB.length; row++){
for (int column = 0; column < standingsB[row].length; column++) {
standingsB[row][column] = Double.parseDouble(tempStandingsArray[arryLgt]);
arryLgt = arryLgt + 1;
}
}
The array has values such as [1.5,7.0] [4.2,4.0] etc...
For the next part I don't really know how it works but from reading other articles here this is the best as I can copy without knowledge
Arrays.sort(standingsB, new Comparator<Double[]>() {
#Override
public int compare(Double[] s1, Double[] s2) {
compare(s1, s2);
}
});
The above fails to compile (with missing return statement) which is to be expected as I have no idea on how to use the Arrays.sort with a comparator. But I'm not even sure if I'm on the right page being as new to Java (and programing in general) as I am.
Thanks for looking!
You're pretty close. Your comparator will depend on what order you want your results in. Let's say you want the rows to be sorted in the natural order of the first element in each row. Then your code would look like:
Arrays.sort(standingsB, new Comparator<Double[]>() {
public int compare(Double[] s1, Double[] s2) {
if (s1[0] > s2[0])
return 1; // tells Arrays.sort() that s1 comes after s2
else if (s1[0] < s2[0])
return -1; // tells Arrays.sort() that s1 comes before s2
else {
/*
* s1 and s2 are equal. Arrays.sort() is stable,
* so these two rows will appear in their original order.
* You could take it a step further in this block by comparing
* s1[1] and s2[1] in the same manner, but it depends on how
* you want to sort in that situation.
*/
return 0;
}
}
};
I think the answer provided by #Tap doesn't fulfill the askers question to 100%. As described, the array is sorted for its value at the first index only. The result of sorting {{2,0},{1,2},{1,1}} would be {{1,2},{1,1},{2,0}} not {{1,1},{1,2},{2,0}}, as expected. I've implemented a generic ArrayComparator for all types implementing the Comparable interface and released it on my blog:
public class ArrayComparator<T extends Comparable<T>> implements Comparator<T[]> {
#Override public int compare(T[] arrayA, T[] arrayB) {
if(arrayA==arrayB) return 0; int compare;
for(int index=0;index<arrayA.length;index++)
if(index<arrayB.length) {
if((compare=arrayA[index].compareTo(arrayB[index]))!=0)
return compare;
} else return 1; //first array is longer
if(arrayA.length==arrayB.length)
return 0; //arrays are equal
else return -1; //first array is shorter
}
}
With this ArrayComparator you can sort multi-dimensional arrays:
String[][] sorted = new String[][]{{"A","B"},{"B","C"},{"A","C"}};
Arrays.sort(sorted, new ArrayComparator<>());
Lists of arrays:
List<String[]> sorted = new ArrayList<>();
sorted.add(new String[]{"A","B"});
sorted.add(new String[]{"B","C"});
sorted.add(new String[]{"A","C"});
sorted.sort(new ArrayComparator<>());
And build up (Sorted)Maps easily:
Map<String[],Object> sorted = new TreeMap<>(new ArrayComparator<>());
sorted.put(new String[]{"A","B"}, new Object());
sorted.put(new String[]{"B","C"}, new Object());
sorted.put(new String[]{"A","C"}, new Object());
Just remember, the generic type must implement the Comparable interface.
Solution with lambda sorting array of int[][] contests example :
Arrays.sort(contests, (a, b)->Integer.compare(b[0], a[0]));
Arrays.sort() expects a single dimensional array while in your case you are trying to pass a multidimensional array.
eg
Double[] d = {1.0,5.2,3.2};
Then you use Arrays.sort(d) since the sort can work on the primitive types or the wrapper types.
Related
So I know how to sort a Java array of ints or floats (or other data types). But what if it was a string array String[] arr = {} where the array contained elements like 2x^2, 4x^4. As you can see, there are several indices that have integers, which could be sorted.
The way I would think to sort this is to splice out the number at an index. Sort those numbers, then map each old index to the new index.
I feel like there is a better way.
The essential question: Does a sorting method exist that can sort a string array based on an integer at a certain index of each index?
If you are wondering, here would be some sample inputs and outputs of an algorithm as such.
Array: {"2x^3","2x^0","1x^1"}
Output:{"2x^3","1x^1","2x^0"} // Sorted based on last index
static final Comparator<String> myComparator =
new Comparator<String>() {
public int compare(String s1, String s2)
{
// split s1 and s2, compare what you need
// and return the result.
// e.g.
// char digit1 = s1[s1.length() - 1];
// char digit2 = s2[s2.length() - 1];
// return (int)(digit1 - digit2);
}
};
Collections.sort(list, myComparator);
// or
Arrays.sort(array, myComparator);
So you are letting someone else's sort method do the sorting for you, you just need to provide a method to say how to compare the items. There are some rules and regulations you need to stick to (e.g. if A < B, B < C then A must be < C).
You can also do it inline/anonymously:
Collections.sort(list, new Comparator<String>() {
public int compare(String s1, String s2) {
...
}
});
I am trying to create a cartesian product method in java that accepts sets as arguments and returns a set pair. The code I have coverts the argumented sets to arrays and then does the cartesian product but i can't add it back to the set pair that i want to return. Is there an easier way to do this? Thanks in advance.
public static <S, T> Set<Pair<S, T>> cartesianProduct(Set<S> a, Set<T> b) {
Set<Pair<S, T>> product = new HashSet<Pair<S, T>>();
String[] arrayA = new String[100];
String[] arrayB= new String[100];
a.toArray(arrayA);
b.toArray(arrayB);
for(int i = 0; i < a.size(); i++){
for(int j = 0; j < b.size(); j++){
product.add(arrayA[i],arrayB[j]);
}
}
return product;
}
this looks simpler,
public static <S, T> Set<Pair<S, T>> cartesianProduct(Set<S> a, Set<T> b) {
Set<Pair<S, T>> product = new HashSet<Pair<S, T>>();
for(S s : a) {
for(T t : b) {
product.add(new ImmutablePair<S, T>(s,t));
}
}
return product;
}
Assuming you're using Pair from Apache Commons, then I think you want the add to be
product.add(Pair.of(arrayA[i],arrayB[j]));
There's no add method for sets that takes two arguments. You have to create the Pair to add to the set. If that doesn't compile, try
product.add(Pair<S,T>.of(arrayA[i],arrayB[j]));
Also, I'm assuming you meant S and T for your arrays, instead of String. There's no reason to preallocate a certain number of elements. Furthermore, the way you've written it, if there are more than 100 elements in either set, toArray will return an all new array with the desired size, but you're not using the function result so that array will be lost. I'd prefer:
S[] arrayA = a.toArray(new S[0]);
T[] arrayB = b.toArray(new T[0]);
The zero-length arrays are just "dummies" whose purpose is to get toArray to return arrays with the correct element type, instead of Object[].
EDIT: Using an enhanced for loop is a lot better than using arrays. See Camilo's answer.
All I need is the simplest method of sorting an ArrayList that does not use the in-built Java sorter. Currently I change my ArrayList to an Array and use a liner sorting code, but I later need to call on some elements and ArrayLists are easier to do that.
you can use anonymous sort.
Collections.sort(<ArrayList name>, Comparator<T>() {
public int compare(T o1, T o2) {
.....
....
}
});
where T is the type you want to sort (i.e String, Objects)
and simply implement the Comparator interface to your own needs
Assuming an ArrayList<String> a...
Easiest (but I'm guessing this is what you're saying you can't use):
Collections.sort(a);
Next easiest (but a waste):
a = new ArrayList<String>(new TreeSet<String>(a));
Assuming "in-built sort" refers to Collections.sort() and you are fine with the sorting algorithm you have implemented, you can just convert your sorted array into an ArrayList
ArrayList list = new ArrayList(Arrays.asList(sortedArray));
Alternatively, you can rewrite your sorting algorithm to work with a List (such as an ArrayList) instead of an array by using the get(int index) and set(int index, E element) methods.
Sorting Arguments passed through Command prompt; without using Arrays.sort
public class Sort {
public static void main(String args[])
{
for(int j = 0; j < args.length; j++)
{
for(int i = j + 1; i < args.length; i++)
{
if(args[i].compareTo(args[j]) < 0)
{
String t = args[j];
args[j] = args[i];
args[i] = t;
}
}
System.out.println(args[j]);
}
}
}
By using Array.sort
import java.util.*;
public class IntegerArray {
public static void main(String args[])
{
int[] num=new int[]{10, 15, 20, 25, 12, 14};
Arrays.sort(num);
System.out.println("Ascending order: ");
for (int i=0; i<num.length; i++)
System.out.print(num[i] + " ");
}
}
Collections.sort(List);
If i remember correctly when you pull an element out of the middle of an arrayList it moves the rest of the elements down automaticly. If you do a loop that looks for the lowest value and pull it out then place it at the end of the arrayList. On each pass i-- for the index. That is use one less. So on a 10 element list you will look at all 10 elements take the lowest one and append it to the end. Then you will look at the first nine and take the lowest of it out and append it to the end. Then the first 8 and so on till the list is sorted.
Check for Comparator in java. You can implement your own sorting using this and use Collections.sort(..) to sort the arraylist using your own Comparator
If you are meant to sort the array yourself, then one of the simplest algorithms is bubble sort. This works by making multiple passes through the array, comparing adjacent pairs of elements, and swapping them if the left one is larger than the right one.
Since this is homework, I'll leave it to you to figure out the rest. Start by visualizing your algorithm, then think about how many passes your algorithm needs to make, and where it needs to start each pass. Then code it.
You also need to understand and solve the problem of how you compare a pair of array elements:
If the elements are instances of a primitive type, you just use a relational operator.
If the elements are instances of reference types, you'll need to use either the Comparable or Comparator interface. Look them up in the javadocs. (And looking them up is part of your homework ...)
Here is a "simple" quicksort implementation:
public Comparable<Object>[] quickSort(Comparable<Object>[] array) {
if (array.length <= 1) {
return array;
}
List<Comparable<Object>> less = new ArrayList<Comparable<Object>>();
List<Comparable<Object>> greater = new ArrayList<Comparable<Object>>();
Comparable<Object> pivot = array[array.length / 2];
for (int i = 0;i < array.length;i++) {
if (array[i].equals(pivot)) {
continue;
}
if (array[i].compareTo(pivot) <= 0) {
less.add(array[i]);
} else {
greater.add(array[i]);
}
}
List<Comparable<Object>> result = new ArrayList<Comparable<Object>>(array.length);
result.addAll(Arrays.asList(quickSort(less.toArray(new Comparable<Object>[less.size()]))));
result.add(pivot);
result.addAll(Arrays.asList(quickSort(greater.toArray(new Comparable<Object>[greater.size()]))));
return result.toArray(new Comparable<Object>[result.size()]);
}
The last operations with arrays and list to build the result can be enhanced using System.arraycopy.
In PHP, you can dynamically add elements to arrays by the following:
$x = new Array();
$x[] = 1;
$x[] = 2;
After this, $x would be an array like this: {1,2}.
Is there a way to do something similar in Java?
Look at java.util.LinkedList or java.util.ArrayList
List<Integer> x = new ArrayList<Integer>();
x.add(1);
x.add(2);
Arrays in Java have a fixed size, so you can't "add something at the end" as you could do in PHP.
A bit similar to the PHP behaviour is this:
int[] addElement(int[] org, int added) {
int[] result = Arrays.copyOf(org, org.length +1);
result[org.length] = added;
return result;
}
Then you can write:
x = new int[0];
x = addElement(x, 1);
x = addElement(x, 2);
System.out.println(Arrays.toString(x));
But this scheme is horribly inefficient for larger arrays, as it makes a copy of the whole array each time. (And it is in fact not completely equivalent to PHP, since your old arrays stays the same).
The PHP arrays are in fact quite the same as a Java HashMap with an added "max key", so it would know which key to use next, and a strange iteration order (and a strange equivalence relation between Integer keys and some Strings). But for simple indexed collections, better use a List in Java, like the other answerers proposed.
If you want to avoid using List because of the overhead of wrapping every int in an Integer, consider using reimplementations of collections for primitive types, which use arrays internally, but will not do a copy on every change, only when the internal array is full (just like ArrayList). (One quickly googled example is this IntList class.)
Guava contains methods creating such wrappers in Ints.asList, Longs.asList, etc.
Apache Commons has an ArrayUtils implementation to add an element at the end of the new array:
/** Copies the given array and adds the given element at the end of the new array. */
public static <T> T[] add(T[] array, T element)
I have seen this question very often in the web and in my opinion, many people with high reputation did not answer these questions properly. So I would like to express my own answer here.
First we should consider there is a difference between array and arraylist.
The question asks for adding an element to an array, and not ArrayList
The answer is quite simple. It can be done in 3 steps.
Convert array to an arraylist
Add element to the arrayList
Convert back the new arrayList to the array
Here is the simple picture of it
And finally here is the code:
Step 1:
public List<String> convertArrayToList(String[] array){
List<String> stringList = new ArrayList<String>(Arrays.asList(array));
return stringList;
}
Step 2:
public List<String> addToList(String element,List<String> list){
list.add(element);
return list;
}
Step 3:
public String[] convertListToArray(List<String> list){
String[] ins = (String[])list.toArray(new String[list.size()]);
return ins;
}
Step 4
public String[] addNewItemToArray(String element,String [] array){
List<String> list = convertArrayToList(array);
list= addToList(element,list);
return convertListToArray(list);
}
You can use an ArrayList and then use the toArray() method. But depending on what you are doing, you might not even need an array at all. Look into seeing if Lists are more what you want.
See: Java List Tutorial
You probably want to use an ArrayList for this -- for a dynamically sized array like structure.
You can dynamically add elements to an array using Collection Frameworks in JAVA. collection Framework doesn't work on primitive data types.
This Collection framework will be available in "java.util.*" package
For example if you use ArrayList,
Create an object to it and then add number of elements (any type like String, Integer ...etc)
ArrayList a = new ArrayList();
a.add("suman");
a.add(new Integer(3));
a.add("gurram");
Now you were added 3 elements to an array.
if you want to remove any of added elements
a.remove("suman");
again if you want to add any element
a.add("Gurram");
So the array size is incresing / decreasing dynamically..
Use an ArrayList or juggle to arrays to auto increment the array size.
keep a count of where you are in the primitive array
class recordStuff extends Thread
{
double[] aListOfDoubles;
int i = 0;
void run()
{
double newData;
newData = getNewData(); // gets data from somewhere
aListofDoubles[i] = newData; // adds it to the primitive array of doubles
i++ // increments the counter for the next pass
System.out.println("mode: " + doStuff());
}
void doStuff()
{
// Calculate the mode of the double[] array
for (int i = 0; i < aListOfDoubles.length; i++)
{
int count = 0;
for (int j = 0; j < aListOfDoubles.length; j++)
{
if (a[j] == a[i]) count++;
}
if (count > maxCount)
{
maxCount = count;
maxValue = aListOfDoubles[i];
}
}
return maxValue;
}
}
This is a simple way to add to an array in java. I used a second array to store my original array, and then added one more element to it. After that I passed that array back to the original one.
int [] test = {12,22,33};
int [] test2= new int[test.length+1];
int m=5;int mz=0;
for ( int test3: test)
{
test2[mz]=test3; mz++;
}
test2[mz++]=m;
test=test2;
for ( int test3: test)
{
System.out.println(test3);
}
In Java size of array is fixed , but you can add elements dynamically to a fixed sized array using its index and for loop. Please find example below.
package simplejava;
import java.util.Arrays;
/**
*
* #author sashant
*/
public class SimpleJava {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try{
String[] transactions;
transactions = new String[10];
for(int i = 0; i < transactions.length; i++){
transactions[i] = "transaction - "+Integer.toString(i);
}
System.out.println(Arrays.toString(transactions));
}catch(Exception exc){
System.out.println(exc.getMessage());
System.out.println(Arrays.toString(exc.getStackTrace()));
}
}
}
What is wrong with this conversion?
public int getTheNumber(int[] factors) {
ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));
Collections.sort(f);
return f.get(0)*f.get(f.size()-1);
}
I made this after reading the solution found in Create ArrayList from array. The second line (sorting) in getTheNumber(...) causes the following exception:
Exception in thread "main" java.lang.ClassCastException: [I cannot be cast to java.lang.Comparable]
What is wrong here? I do realize that sorting could be done with Arrays.sort(), I'm just curious about this one.
Let's consider the following simplified example:
public class Example {
public static void main(String[] args) {
int[] factors = {1, 2, 3};
ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));
System.out.println(f);
}
}
At the println line this prints something like "[[I#190d11]" which means that you have actually constructed an ArrayList that contains int arrays.
Your IDE and compiler should warn about unchecked assignments in that code. You should always use new ArrayList<Integer>() or new ArrayList<>() instead of new ArrayList(). If you had used it, there would have been a compile error because of trying to pass List<int[]> to the constructor.
There is no autoboxing from int[] to Integer[], and anyways autoboxing is only syntactic sugar in the compiler, so in this case you need to do the array copy manually:
public static int getTheNumber(int[] factors) {
List<Integer> f = new ArrayList<Integer>();
for (int factor : factors) {
f.add(factor); // after autoboxing the same as: f.add(Integer.valueOf(factor));
}
Collections.sort(f);
return f.get(0) * f.get(f.size() - 1);
}
You are trying to cast int[] to Integer[], this is not possible.
You can use commons-lang's ArrayUtils to convert the ints to Integers before getting the List from the array:
public int getTheNumber(int[] factors) {
Integer[] integers = ArrayUtils.toObject(factors);
ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(integers));
Collections.sort(f);
return f.get(0)*f.get(f.size()-1);
}
there are two cause of this exception:
1
Arrays.asList(factors) returns a List<int[]> where factors is an int array
2
you forgot to add the type parameter to:
ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));
with:
ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));
resulting in a compile-time error:
found : java.util.List<int[]>
required: java.util.List<java.lang.Integer>
Use java.utils.Arrays:
public int getTheNumber(int[] factors) {
int[] f = (int[])factors.clone();
Arrays.sort(f);
return f[0]*f[(f.length-1];
}
Or if you want to be efficient avoid all the object allocation just actually do the work:
public static int getTheNumber(int[] array) {
if (array.length == 0)
throw new IllegalArgumentException();
int min = array[0];
int max = array[0];
for (int i = 1; i< array.length;++i) {
int v = array[i];
if (v < min) {
min = v;
} else if (v > max) {
max = v;
}
}
return min * max;
}
I think you have found an example where auto-boxing doesn't really work. Because Arrays.asList(T... a) has a varargs parameter the compiler apparently considers the int[] and returns a List<int[]> with a single element in it.
You should change the method into this:
public int getTheNumber(Integer[] factors) {
ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));
Collections.sort(f);
return f.get(0) * f.get(f.size() - 1);
}
and possibly add this for compatibility
public int getTheNumber(int[] factors) {
Integer[] factorsInteger = new Integer[factors.length];
for(int ii=0; ii<factors.length; ++ii) {
factorsInteger[ii] = factors[ii];
}
return getTheNumber(factorsInteger);
}
Arrays.asList(factors) returns a List<int[]>, not a List<Integer>. Since you're doing new ArrayList instead of new ArrayList<Integer> you don't get a compile error for that, but create an ArrayList<Object> which contains an int[] and you then implicitly cast that arraylist to ArrayList<Integer>. Of course the first time you try to use one of those "Integers" you get an exception.
This works from Java 5 to 7:
public int getTheNumber(Integer... factors) {
ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));
Collections.sort(f);
return f.get(0)*f.get(f.size()-1);
}
In Java 4 there is no vararg... :-)
this is from Java API
"sort
public static void sort(List list)
Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list)."
it has to do with implementing the Comparable interface
As far as I understand it, the sort function in the collection class can only be used to sort collections implementing the comparable interface.
You are supplying it a array of integers.
You should probably wrap this around one of the know Wrapper classes such as Integer.
Integer implements comparable.
Its been a long time since I have worked on some serious Java, however reading some matter on the sort function will help.