Sorting an ArrayList / HashMap with key - java

I have an ArrayList
static ArrayList<term> terms = new ArrayList<term>();
and a HashMap
static HashMap<String,ArrayList<Integer>> inverted_index = new HashMap<String,ArrayList<Integer>>();
This is my class term
public class term {
int docID;
String tokenName;
public term(String tokenName, int docID)
{
this.tokenName = tokenName;
this.docID = docID;
}
public int getDocID() {
return docID;
}
public String getTokenName() {
return tokenName;
}
public String toString(){
return tokenName + " " + docID ;
}}
I want to sort it by tokenName.
I did this
Collections.sort(terms, new Comparator<term>(){
public int compare(term term1, term term2){
return term1.tokenName.compareTo(term2.tokenName);
}
});
Now when I print terms, I do get the sorted order.
Now I call this function
public static void createInvertedIndex(){
inverted_index.clear();
for(int i=0; i<terms.size(); i++){
ArrayList<Integer> doc_list = new ArrayList<Integer>();
if(!inverted_index.containsKey(terms.get(i).tokenName)){
doc_list.add(terms.get(i).docID);
if(i+1 < terms.size()){
if(terms.get(i).tokenName.equals(terms.get(i+1).tokenName)){
while((i+1 < terms.size()) && terms.get(i).tokenName.equals(terms.get(i+1).tokenName))
{
i++;
doc_list.add(terms.get(i).docID);
}
}
}
//System.out.println(terms.get(i)); ------ Get Sorted Terms here
inverted_index.put(terms.get(i).tokenName, doc_list);
}
}
System.out.println(inverted_index); // ------ Get Unsorted terms in this
}
I don't get sorted inverted_index.
Do I need to sort it too?
If so, how to do that?
I want the output in sorted order.

inverted_index is a HashMap and HashMap is not sorted. You need to use a SortedMap for this, like TreeMap.

Related

HashMap Storing only one entry

I'm taking a binary String like this:
010010010000110100001010
as a String, converting it to Integer Array like this:
int[] DD = new DD[binString.length()];
char temp = binString.charAt(i);
int binData = Character.getNumericValue(temp);
DD[i] = binData;
and I'm tying to save these Integer values in to HashMap(I have to store into a HashMap as per instructions given to me) like this:
Map<String, Integer> toMemory = new HashMap<String, Integer>();
for(int i=0;i<binString.length();i++) {
char temp = binString.charAt(i);
int binData = Character.getNumericValue(temp);
DD[i] = binData;
if((DD[i] & (DD[i]-1) ) == 0) {
toMemory.put(new String("ON"), new Integer(DD[i]));
} else {
toMemory.put(new String("ON"), new Integer(DD[i]));
}
}
for(String s: toMemory.keySet()) {
if(s.startsWith("ON")) {
System.out.println(toMemory.get(s));
}
}
The issue I'm facing here is that, only one entry is being stored in the HashMap, say {"ON",0}. And no other values are being stored. My expected output is this:
{"ON" , 1 , "OFF" , 0, "ON" , 1 .........}
Is there any better way to store the values to get my expected output? Any help will be much appreciated.
P.S: Please ignore the recurring code, and I'm relatively new to programming.
Your usage of a Map is flawed. Maps take a unique key and return a value.
You are trying to use duplicate keys. Instead, look at using a List with a wrapper class:
class ClassName {
public String status;
public int value;
public ClassName(String status, int value){
this.status = status;
this.value = value;
}
}
List<ClassName> list = new ArrayList();
To add to the list, create a new instance of your class and call List#add:
list.add(new ClassName("ON", 1));
as Infuzed Guy said, you are using the Map the wrong way. It's a unique "key to value mapping".
As long as you are using several times the same key and want to store all the dada, you need to use a List.
Here is what I could come up with the little you gave us: test it here
import java.util.LinkedList;
import java.util.List;
class Main {
public static void main(String[] args) {
class Tuple<X, Y> { //The wrapper object
public final X x;
public final Y y;
public Tuple(X x, Y y) { //Object constructor
this.x = x;
this.y = y;
}
public String toString() //Here for printing purpose
{
return "\"" + this.x + "\", " + this.y;
}
}
//Note here te use of List
List<Tuple> toMemory = new LinkedList<>();
String binString = "10100100101100101011";
int[] DD = new int[binString.length()];
for(int i=0; i < binString.length(); ++i)
{
//Here I use the char value
//to get the by subtraction
DD[i] = binString.charAt(i) - '0';
if(DD[i] == 1) //Simple check with the int value
{
toMemory.add(new Tuple<>("ON", DD[i]));
}
else
{
toMemory.add(new Tuple<>("OFF", DD[i]));
}
}
//Print the List
System.out.print("{ ");
for(Tuple s: toMemory) {
System.out.print(s +", ");
}
System.out.println("}");
}
}

Sort ArrayList items by name

I am trying to rearrange an ArrayList based on the name of the items to be on specific index.
My list currently is this:
"SL"
"TA"
"VP"
"SP"
"PR"
and i want to rearrange them to:
"SL"
"SP"
"TA"
"PR"
"VP"
but based on the name and not in the index.
I have tried this:
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("SL")){
orderedDummyJSONModelList.add(list.get(i));
}
}
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("SP")){
orderedDummyJSONModelList.add(list.get(i));
}
}
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("TA")){
orderedDummyJSONModelList.add(list.get(i));
}
}
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("PR")){
orderedDummyJSONModelList.add(list.get(i));
}
}
for (int i=0; i< list.size(); i++){
if (list.get(i).getCategoryName().equals("VP")){
orderedDummyJSONModelList.add(list.get(i));
}
}
and it works fine, but i want to know if there is a more efficient way to do in 1 for loop or maybe a function. I do not wish to do it like this:
orderedDummyJSONModelList.add(list.get(0));
orderedDummyJSONModelList.add(list.get(3));
orderedDummyJSONModelList.add(list.get(1));
orderedDummyJSONModelList.add(list.get(4));
orderedDummyJSONModelList.add(list.get(2));
Which also works. Any ideas?
You can use Collection.Sort method as Collection.Sort(list) since list is a List<String> you will be fine. But if you want to implement a new comparator:
Collections.sort(list, new NameComparator());
class NameComparator implements Comparator<String> { //You can use classes
#Override
public int compare(String a, String b) { //You can use classes
return a.compareTo(b);
}
}
EDIT:
You can define a class comparator for your needs:
class ClassComparator implements Comparator<YourClass> { //You can use classes
#Override
public int compare(YourClass a, YourClass b) { //You can use classes
return a.name.compareTo(b.name);
}
}
The key thing here is: you need to get clear on your requirements.
In other words: of course one can shuffle around objects stored within a list. But: probably you want to do that programmatically.
In other words: the correct approach is to use the built-in Collection sorting mechanisms, but with providing a custom Comparator.
Meaning: you better find an algorithm that defines how to come from
"SL"
"TA"
"VP"
"SP"
"PR"
to
"SL"
"SP"
"TA"
"PR"
"VP"
That algorithm should go into your comparator implementation!
The point is: you have some List<X> in the first place. And X objects provide some sort of method to retrieve those strings you are showing here. Thus you have to create a Comparator<X> that works on X values; and uses some mean to get to those string values; and based on that you decide if X1 is <, = or > than some X2 object!
here´s an answer just specific for your problem working just for the given output. If the List contains anything else this might break your ordering, as there is no rule given on how to order it and the PR just randomly appears in the end.
public static void main(String[] args) {
List<String> justSomeNoRuleOrderingWithARandomPRInside = new ArrayList<String>();
justSomeNoRuleOrderingWithARandomPRInside.add("SL");
justSomeNoRuleOrderingWithARandomPRInside.add("TA");
justSomeNoRuleOrderingWithARandomPRInside.add("VP");
justSomeNoRuleOrderingWithARandomPRInside.add("SP");
justSomeNoRuleOrderingWithARandomPRInside.add("PR");
java.util.Collections.sort(justSomeNoRuleOrderingWithARandomPRInside, new NameComparator());
for(String s : justSomeNoRuleOrderingWithARandomPRInside) {
System.out.println(s);
}
}
static class NameComparator implements Comparator<String> { //You can use classes
#Override
public int compare(String a, String b) { //You can use classes
// Lets just add a T in front to make the VP appear at the end
// after TA, because why not
if (a.equals("PR")) {
a = "T"+a;
} else if(b.equals("PR")) {
b = "T"+b;
}
return a.compareTo(b);
}
}
O/P
SL
SP
TA
PR
VP
But honestly, this solution is crap, and without any clear rule on how to order these this will be doomed to fail as soon as you change anything as #GhostCat tried to explain.
How about this
// define the order
List<String> ORDER = Arrays.asList("SL", "SP", "TA", "PR", "VP");
List<MyObject> list = ...
list.sort((a, b) -> {
// lamba syntax for a Comparator<MyObject>
return Integer.compare(ORDER.indexOf(a.getString()), ORDER.indexOf(b.getString());
});
Note that this will put any strings that aren't defined in the ORDER list at the start of the sorted list. This may or may not be acceptable - it may be worth checking that only valid strings (i.e. members of ORDER) appear as the result of MyObject.getString().
Use a hashmap to store the weight of all strings (Higher the value of the hashmap means the later this string should come in the final list).
Using a Hashmap, so you can expand it later for other strings as well. It'll be easier to enhance in future.
Finally, Use a custom Comparator to do it.
Required Setup:
List<String> listOfStrings = Arrays.asList("SL", "TA", "VP", "SP", "PR");
HashMap<String, Integer> sortOrder = new HashMap<>();
sortOrder.put("SL", 0);
sortOrder.put("TA", 1);
sortOrder.put("VP", 2);
sortOrder.put("SP", 3);
sortOrder.put("PR", 4);
Streams:
List<String> sortedList = listOfStrings.stream().sorted((a, b) -> {
return Integer.compare(sortOrder.get(a), sortOrder.get(b));
}).collect(Collectors.toList());
System.out.println(sortedList);
Non-Stream:
Collections.sort(listOfStrings, (a, b) -> {
return Integer.compare(sortOrder.get(a), sortOrder.get(b));
});
OR
listOfStrings.sort((a, b) -> {
return Integer.compare(sortOrder.get(a), sortOrder.get(b));
});
System.out.println(listOfStrings);
Output:
[SL, TA, VP, SP, PR]
You can build an index map using a LinkedHashMap. This will be used to lookup the order which to sort using the category names of your items.
ItemSorting
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ItemSorting {
public static void main(String[] args) {
List<Item> list = new ArrayList<Item>();
IndexMap indexMap = new IndexMap("SL", "SP", "TA", "PR", "VP");
ItemComparator itemComparator = new ItemComparator(indexMap);
list.add(new Item("SL"));
list.add(new Item("TA"));
list.add(new Item("VP"));
list.add(new Item("SP"));
list.add(new Item("PR"));
Collections.sort(list, itemComparator);
for (Item item : list) {
System.out.println(item);
}
}
}
ItemComparator
import java.util.Comparator;
public class ItemComparator implements Comparator<Item> {
private IndexMap indexMap;
public IndexMap getIndexMap() {
return indexMap;
}
public void setIndexMap(IndexMap indexMap) {
this.indexMap = indexMap;
}
public ItemComparator(IndexMap indexMap) {
this.indexMap = indexMap;
}
#Override
public int compare(Item itemA, Item itemB) {
if (itemB == null) return -1;
if (itemA == null) return 1;
if (itemA.equals(itemB)) return 0;
Integer valA = indexMap.get(itemA.getCategoryName());
Integer valB = indexMap.get(itemB.getCategoryName());
if (valB == null) return -1;
if (valA == null) return 1;
return valA.compareTo(valB);
}
}
IndexMap
import java.util.LinkedHashMap;
public class IndexMap extends LinkedHashMap<String, Integer> {
private static final long serialVersionUID = 7891095847767899453L;
public IndexMap(String... indicies) {
super();
if (indicies != null) {
for (int i = 0; i < indicies.length; i++) {
this.put(indicies[i], new Integer(i));
}
}
}
}
Item
public class Item {
private String categoryName;
public Item(String categoryName) {
super();
this.categoryName = categoryName;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((categoryName == null) ? 0 : categoryName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Item other = (Item) obj;
if (categoryName == null) {
if (other.categoryName != null) return false;
} else if (!categoryName.equals(other.categoryName)) return false;
return true;
}
#Override
public String toString() {
return String.format("Item { \"categoryName\" : \"%s\" }", categoryName);
}
}
Result
Item { "categoryName" : "SL" }
Item { "categoryName" : "SP" }
Item { "categoryName" : "TA" }
Item { "categoryName" : "PR" }
Item { "categoryName" : "VP" }
You coud define a helper method like this one:
public static int get(String name) {
switch (name) {
case "SL":
return 1;
case "SP":
return 2;
case "TA":
return 3;
case "PR":
return 4;
case "VP":
return 5;
default:
return 6;
}
}
and write in your main method something like:
ArrayList<String> al = new ArrayList<>();
al.add("SL");
al.add("TA");
al.add("VP");
al.add("SP");
al.add("PR");
Collections.sort(al, (o1, o2) -> return get(o1) - get(o2); );
al.forEach((s) -> System.out.println(s));
You can create a Map that maintains the position. When you iterate through the unordered list just get the position of that string value and insert into new array(not arraylist), then later if required you can convert that array to ArrayList.
Example code:
Map<String,Integer> map = new HashMap<>(); //you can may be loop through and make this map
map.put("SL", 0);
map.put("SP", 1);
map.put("TA",2);
map.put("PR",3);
map.put("VP",3);
List<String> list1 // your unordered list with values in random order
String[] newArr = new String[list1.size()];
for(String strName: list1){
int position = map.get(strName);
arr[position] = strName;
}
//newArr has ordered result.

how to compare two arraylist<Contacts> in java

I am comparing two arraylist (Contacts .java is an pojo class). First Arraylist contains some Items and second arraylist contains some Items. By comparing two list, if both list contains same element it should not be added and else added to first list. But I cannot do it. Below is my code. Help will be appreciated.
public void insertmanualandxmldata()
{
mContacts = storage.getarraylist(); // Arraylist
if(mContacts != null)
{
for(int i=0; i<mContacts.size(); i++)
{
ContactVO mShareddata = mContacts.get(i);
//mParsedDataSetList arraylist
for(int j=0; j<mParsedDataSetList.size(); j++)
{
ContactVO mXmldata = mParsedDataSetList.get(j);
if(mShareddata.getNumber().contains(mXmldata.getNumber()))
{
mContacts.add(mXmldata);
}
}
}
storage.savearraylist(mContacts);
}
else
{
storage.savearraylist(mParsedDataSetList);
}
}
Implement Comparable
private class ContactsVO implements Comparable<ContactsVO>{
int number;
#Override
public int compareTo(ContactsVO that)
{
if (this.number> that.number)
return 1;
else if (this.number< that.number)
return -1;
else
return 0;
}
}
And your logic.. Add contents of list 2 to list 1. while adding we have to compare if list 1 already has that item.
for(int j=0; j < mParsedDataSetList.size(); j++)
{
ContactVO mXmldata = mParsedDataSetList.get(j);
boolean exists = false;
for(int i=0; i< mContacts.size(); i++)
{
ContactVO mShareddata = mContacts.get(i);
if(mShareddata.comprareTo(mXmldata) == 0)
{
exists = true;
break;
}
}
if(!exists)
{
mContacts.add(mXmldata);
}
}
You could implement a class that extends ArrayList and create a Comparator like this:
public static Comparator<T> Comp = new Comparator<T>(){
public int compare(Type e1, Type e2){
return (e1.getSomething().compareTo(e2.getSomething()));
}
};
If you have never used comparators before here is a good tutorial https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html
What comparators basically do is to provide a criteria for comparing elements.
There are two approaches by implementing comparator or comparable.
For your requirement I would suggest you can implements Comparable in your ContactVO class. And override compareTo method.
private class ContactsVO implements Comparable<ContactsVO> {
private Integer number;
// Remaining attributes and their getter setter.
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
#Override
public int compareTo(ContactsVO compareWith) {
if (this.getNumber() > compareWith.getNumber())
return 1;
else if (this.getNumber() < compareWith.getNumber())
return -1;
else
return 0;
}
}
If comparing attribute (in our case is number) implements Comparable then we can rewrite compareTo method as
#Override
public int compareTo(ContactsVO compareWith) {
return this.getNumber().compareTo(compareWith.getNumber());
}
Note: Some basic data types such as Integer, String implements Comparable.
Here contactList1 and contactList2 is your two list of POJO class Contacts
Set<Contacts> contactList3 = new HashSet<Contacts>(contactList1);
contactList3.addAll(contactList2);
ArrayList<Contacts> newList = new ArrayList<Contacts>(contactList3);
System.out.println("New List :"+newList);
Try to use LinkedHashSet which will not allow duplicates :
ArrayList arrayList1 = new ArrayList();
ArrayList arrayList2 = new ArrayList();
ArrayList arrayList3 = new ArrayList();
arrayList3.addAll(arrayList1);
arrayList3.addAll(arrayList2);
HashSet hashSet = new HashSet();
hashSet.addAll(arrayList3);
arrayList3.clear();
arrayList3.addAll(hashSet);
Note : when you required to maintain ordering of you list item use LinkedHashSet instead of HashSet.

Android sort array

i have a string array consisting of a name and a score. I want to sort that array by score. Problem is, considering it's a string array, the scores are strings which results in 13,16,2,5,6 and not 2,5,6,13,16. I am using this code:
int spaceIndex;
String[][] scoreboard;
String[] playername;
String[] score;
int sbsize;
array1.add("Thomas" + ":" + 5);
array1.add("Blueb" + ":" + 6);
array1.add("James" + ":" + 16);
array1.add("Hleb" + ":" + 13);
array1.add("Sabbat" + ":" + 2);
sbsize = array1.size();
scoreboard = new String[sbsize][2];
playername = new String[sbsize];
score = new String[sbsize];
pos2 = new int[sbsize];
for (int i=0; i<array1.size(); i++)
{
spaceIndex = array1.get(i).indexOf(':');
scoreboard[i][0] = array1.get(i).substring(0, spaceIndex);
scoreboard[i][1] = array1.get(i).substring(spaceIndex+1, array1.get(i).length());
}
Arrays.sort(scoreboard, new Comparator<String[]>() {
#Override
public int compare(String[] entry1, String[] entry2) {
String time1 = entry1[1];
String time2 = entry2[1];
return time1.compareTo(time2);
}
});
What is the solution?
Cast them to int. As I recall, something like...
Arrays.sort(scoreboard, new Comparator<String[]>() {
#Override
public int compare(String[] entry1, String[] entry2) {
Integer time1 = Integer.valueOf(entry1[1]);
Integer time2 = Integer.valueOf(entry2[1]);
return time1.compareTo(time2);
}
});
Also you can make simple value object class for easier manipulations. Like...
class Player
{
public String name;
public int score;
}
And after that you can make
Player[] scoreboard = ...
Arrays.sort(scoreboard, new Comparator<Player>() {
#Override
public int compare(Player player1, Player player2) {
if(player1.score > player2.score) return 1;
else if(player1.score < player2.score) return -1;
else return 0;
}
});
Edit:
I recommend you to understand the basic OOP principles, this will help you a lot in the beginning.
Edit 2: Java 8 (with functional interface and a lambda):
Arrays.sort(scoreboard, (player1, player2) -> {
Integer time1 = Integer.valueOf(player1[1]);
Integer time2 = Integer.valueOf(player2[1]);
return time1.compareTo(time2);
});
This is the easy way of Sorting String Array:
Arrays.sort(mystringarray);
Use
java.util.Arrays.sort(yourArray, new Comparator<String>() {
#Override
public int compare(String object1, String object2) {
return Integer.valueOf(object1).compareTo(Integer.valueOf(object2));
}
});
Comparator will compare your strings as integers.
ArrayList<String> names= new ArrayList<String>();
names.add("sathish");
names.add("Ravi");
names.add("Praksh");
names.add("pavithara");
names.add("Duraga");
names.add("uma");
names.add("Upendar");
System.out.println("Before sorting");
System.out.println("Names : "+names);
Collections.sort(names, new Comparator<String>() {
#Override
public int compare(String lhs, String rhs) {
return lhs.compareToIgnoreCase(rhs);//Ascending order.
//return (lhs.compareToIgnoreCase(rhs)*(-1));//Descending order.
}
});
System.out.println("After sorting");
System.out.println("Names : "+names);
output:
Before sorting
Names : [sathish, Ravi, Praksh, pavithara, Duraga, uma, Upendar]
After sorting
Names : [Duraga, pavithara, Praksh, Ravi, sathish, uma, Upendar]
If possible use better data structure for your problem, use HashMap, with name to score mapping and , sort the hashmap with values.
If you want to go with arraylist as described by you, before sorting, convert them into integer and sort, then back to string.
You would probably be better off storing the names + results in objects, then storing those in an ArrayList. You can then sort very easily using a custom comparator, see the link for a simple example: http://www.javabeat.net/tips/20-sorting-custom-types-in-java.html
Score should be a class like
public class HighScore Comparable<HighScore>
{
private String name;
private int score;
public Score( String name, int score )
{
this.name = name;
this.score = score;
}//cons
//getters
public String getName() {
return name;
}//met
public int getScore() {
return score;
}//met
#Override
public int compareTo( HighScrore b )
{
int diffScore = score - b.score;
if( diffScore != 0)
return diffScore;
else
return name.compareTo( b.name );
}//met
public boolean equals( Object o )
{
if( !(o instanceof HighScore))
return false;
HighScore b = (HighScore) o;
return score == b.score && name.equals( b.name );
}//met
}//class
Then you can build score objects,
String[] stringParts[];
List<HighScore> listHighScore = new ArrayList<HighScore>();
for (int i=0; i<array1.size(); i++)
{
stringParts = array1.get(i).split(':');
listHighScore.add( new HighScore( stringParts[ 0 ], Integer.parseInt( stringParts[ 1 ])) );
}//for
put them in a List and sort them through
Collections.sort( list );
Regards,
Stéphane
You can use ArrayList instead of Array.
Please check this link

Sorting 2D array of strings in Java

I know that this question might have been asked before, but I was not able to find a fit answer. So say I have this array:
String[][] theArray = {
{"james", "30.0"},
{"joyce", "35.0"},
{"frank", "3.0"},
{"zach", "34.0"}};
Is there a way to descendingly sort this array by the second element of each sub-element. So I would get something like this.
theArray = {
{"joyce", "35.0"},
{"zach", "34.0"},
{"james", "30.0"},
{"frank", "3.0"}};
Use Arrays.sort(arr, comparator) with a custom comparator:
Arrays.sort(theArray, new Comparator<String[]>(){
#Override
public int compare(final String[] first, final String[] second){
// here you should usually check that first and second
// a) are not null and b) have at least two items
// updated after comments: comparing Double, not Strings
// makes more sense, thanks Bart Kiers
return Double.valueOf(second[1]).compareTo(
Double.valueOf(first[1])
);
}
});
System.out.println(Arrays.deepToString(theArray));
Output:
[[joyce, 35.0], [zach, 34.0], [james, 30.0], [frank, 23.0]]
Beware:
you will be sorting the array you passed in, Arrays.sort() will not return a new array (in fact it returns void). If you want a sorted copy, do this:
String[][] theCopy = Arrays.copyOf(theArray, theArray.length);
And perform the sorting on theCopy, not theArray.
You must use the Arrays.sort() method. This method takes a Comparator as argument. The sort method delegates to the comparator to determine if one element of the array must be considered bigger, smaller or equal to another element. Since every element of the outer array is an array, the comparator will have to compare arrays (of Strings).
The arrays must be compared based on the value of their second element. This second element is a String which in fact represents a double number. So you'll have to transorm the strings into numbers, else the order will be lexicographical (20 come before 3) rather than numerical.
The comparator could thus look like this :
public class StrinArrayComparator implements Comparator<String[]> {
#Override
public int compare(String[] array1, String[] array2) {
// get the second element of each array, andtransform it into a Double
Double d1 = Double.valueOf(array1.[1]);
Double d2 = Double.valueOf(array2.[1]);
// since you want a descending order, you need to negate the
// comparison of the double
return -d1.compareTo(d2);
// or : return d2.compareTo(d1);
}
}
If you want to move away from arrays, here's a variation that uses List<Record> and a RecordComparator that implements Comparator<Record>.
Console:
joyce 35.0
zach 34.0
james 30.0
frank 23.0
Code:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/** #see http://stackoverflow.com/questions/5064027 */
public class ComparatorTest {
public static void main(String[] args) {
List<Record> list = new ArrayList<Record>(Arrays.asList(
new Record("james", "30.0"),
new Record("joyce", "35.0"),
new Record("frank", "23.0"),
new Record("zach", "34.0")));
print(list, Sort.DESCENDING, Field.D);
}
private static void print(List<Record> list, Sort s, Field f) {
RecordComparator rc = new RecordComparator(s, f);
Collections.sort(list, rc);
for (Record r : list) {
System.out.println(r);
}
}
}
class Record {
private String s;
private Double d;
public Record(String name, String number) {
this.s = name;
this.d = Double.valueOf(number);
}
#Override
public String toString() {
return s + " " + d;
}
public int compareTo(Field field, Record record) {
switch (field) {
case S: return this.s.compareTo(record.s);
case D: return this.d.compareTo(record.d);
default: throw new IllegalArgumentException(
"Unable to sort Records by " + field.getType());
}
}
}
enum Sort { ASCENDING, DESCENDING; }
enum Field {
S(String.class), D(Double.class);
private Class type;
Field(Class<? extends Comparable> type) {
this.type = type;
}
public Class getType() {
return type;
}
}
class RecordComparator implements Comparator<Record> {
private Field field;
private Sort sort;
public RecordComparator(Sort sort, Field field) {
this.sort = sort;
this.field = field;
}
#Override
public final int compare(Record a, Record b) {
int result = a.compareTo(field, b);
if (sort == Sort.ASCENDING) return result;
else return -result;
}
}
You seem to be living in object denial. Those inner arrays look a lot like information about a Person (with the name and some value, maybe a score).
What you'd want to do is to write a custom class to hold that information:
public class Person {
private final String name;
private final double score;
public Person(final String name, final double score) {
this.name=name;
this.score=score;
}
public String getName() {
return name;
}
public double getScore() {
return score;
}
}
Then, when you want to sort them, you simply implement a Comparator<Person> that specifies how you want them sorted:
public PersonScoreComparator implements Comparator<Person> {
public int compare(Person p1, Person p2) {
return Double.compare(p1.getScore(), p2.getScore());
}
}
Alternatively, you could have the Person class itself implement Comparable<Person> by adding this method:
public int compareTo(Person other) {
return Double.compare(getScore(), other.getScore());
}
-Create list out of this array using Arrays.toList()
-Design comparator using java.lang.comparator and write logic for sorting every even elements
There are several sort methods in java.util.Arrays. Two of them take custom Comparators. Simply provide a comparator comparing the second element of the inner arrays.
public static void main(String[] args)
{
String Name[][]={{"prakash","kumar"},{"raj","kappor"},{"vinod","bhart"}};
String str[]=new String[2];
for(int j=0; j<Name.length;j++)
{
for (int i=0 ; i<2; i++)
{
str[i]=Name[j][i];
}
for(int i=0;i<str.length;i++)
{
for(int k=i+1;k<str.length;k++)
{
if(str[i].compareTo(str[k])>0)
{
String temp= str[i];
str[i]=str[k];
str[k]=temp;
}
}
System.out.print(str[i]+ " ");
}
System.out.println();
}
}
}
/**
*
* #param array - 2D array required to be arranged by certain column
* #param columnIndex - starts from 0; this will be the main comparator
* #param hasHeaders - true/false; true - ignore the first row. False -
* first row it's also compared and arranged
* #return - the new arranged array
*/
private String[][] arrangeArray(String[][] array, int columnIndex, boolean hasHeaders) {
int headersExists = 0;
if (hasHeaders) {
headersExists = 1;
}
for (int i = headersExists; i < array.length; i++) {
for (int j = headersExists; j < array.length; j++) {
if (array[i][columnIndex].compareTo(array[j][columnIndex]) < 0){
String[] temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}

Categories

Resources