How do I sort a multidimensional array in order of appearance in Java?
If the title is not clear, let me give you an example:
I have an array sorted by the first column - date
and I need to sort it again in the order the value appears in the columnname
data[100][4]
date | name | text | type
-----+------+------+------
2222 | z | wwww | 2
2221 | z | qqqq | 1
2220 | c | dasa | 2
2219 | b | dsad | 1
2218 | z | dfsa | 2
2217 | c | dasd | 1
And here is the sorted array:
order[100][4]
date | name | text | type
-----+------+------+------
2222 | z | wwww | 2
2221 | z | qqqq | 1
2218 | z | dfsa | 2
2220 | c | dasa | 2
2217 | c | dasd | 1
2219 | b | dsad | 1
I was thinking about concatenating this data into one row and inserting some character between the columns to get it back in the future by adding in ArrayList
and then extracting by name. I added data[i][1]
in HashMap
to quantify the number of unique values, so I could find out the number of times to loop. And the order of the names comes, which puzzles me because it HashMap
doesn't maintain order.
Does anyone know how it can be sorted without all these problems?
source to share
Have an object representing a data record with date, name, text and type and implement the interface Comparable
. The interface Comparable
effectively allows inequality operations on objects, and uses the Java API for any kind of object mapping (which is used for sorting). Then, to sort the data according to a given field, include a static variable in the data object class that represents which field will be sorted.
class Data implements Comparable<Data>
{
int date; // field 1
String name; // field 2
String text; // field 3
int type; // field 4
static int sortField;
static final int DATE = 1;
static final int NAME = 2;
static final int TEXT = 3;
static final int TYPE = 4;
// put constructor here
//compareTo function for sorting
public int compareTo(Data other)
{
if (sortField == DATE)
{
if (date < other.date) return -1;
if (date > other.date) return 1;
else return 0;
}
if (sortField == NAME)
{
return name.compareTo(other.name);
}
if (sortField == TEXT)
{
return text.compareTo(other.text);
}
else
{
if (type < other.type) return -1;
if (type > other.type) return 1;
else return 0;
}
}
}
Then all you have to do is put the objects in ArrayList
and sort them
ArrayList<Data> list = new ArrayList<Data>();
//put Data objects into list here
//to sort
Data.sortField = Data.DATE; //sort by date - change as needed
Collections.sort(list);
source to share
I used @ Aderis's idea of โโcreating a class, but the sorting method is slightly different. Code was posted here to initialize an array, but someone removed it. Anyway, I also used it.
String[][] myArr = { { "2222", "b", "dfsa", "2" },
{ "2221", "z", "wwww", "2" }, { "2220", "c", "qqqq", "1" },
{ "2219", "z", "dasa", "2" }, { "2218", "b", "dsad", "1" } };
HashMap<String,String> hashData = new HashMap<>();
for (int i = 0; i < myArr.length; i++) hashData.put(myArr[i][1],myArr[i][1]);
int unique_entries = hashData.size();
ArrayList<Data> list = new ArrayList<Data>();
ArrayList<Data> list_sorted = new ArrayList<Data>();
for (int i = 0; i < myArr.length; i++){
Data temp = new Data(myArr[i][0],myArr[i][1],myArr[i][2],Integer.parseInt(myArr[i][3]));
list.add(temp);
}
for (int k = 0; k < unique_entries; k++){
boolean flag = true;
ArrayList<Integer> elements = new ArrayList<>();
int list_elements = list.size();
for (int i = 0; i < list_elements; i++){
if (flag){
list_sorted.add(list.get(i));
elements.add(i);
flag = false;
continue;
}
int list_sorted_elements = list_sorted.size();
for (int j = 0; j < list_sorted_elements; j++){
if (list_sorted.get(j).name.contains(list.get(i).name)){
list_sorted.add(list.get(i));
elements.add(i);
break;
}
}
}
for (int i = 0; i < elements.size(); i++){
int temp = elements.get(i);
if (i != 0) temp = temp - i;
list.remove(temp);
}
}
As you can see, in order to set the number of unique elements, I add them to HashMap
and check its size. I populate ArrayList
my data objects and add the sorted data to another ArrayList
, then remove that data from the unsorted list and start sorting the rest. There are as many cycles as there are unique names.
I don't think this is the optimal way. But this is the only way I know. If anyone knows a faster way, I will accept their message.
source to share
Convert this 2d array to HashMap. The object part will contain that particular array element.
Get keyset .. convert a set of keys to a list. sort this list .. iterate over the list and get its corresponding array element from the map.
for example the code:
String[][] myArr = new String[4][3];
for (int i=0; i<myArr.length; i++) {
myArr[i][0] = (i+1)+"1";
myArr[i][1] = (i+1)+"2";
myArr[i][2] = (i+1)+"3";
}
Map<String, Object> map = new HashMap<String, Object>();
for (int i=myArr.length-1; i>=0; i--) {
map.put(myArr[i][0], myArr[i]);
}
List<String> keyList = new ArrayList<String>(map.keySet());
Collections.sort(keyList);
String[][] myNewArray = new String[4][3];
int a =0;
for (String s : keyList) {
myNewArray[a++] = ((String[])map.get(s));
}
I am using String, in your case it is date. Even if it's something else, you can use a comparable or compactor to sort that list.
Use the sort key as the key on the map.
source to share