i have two ArrayLists:
List<String> names = new ArrayList<String>(10);
List<Drawable> drawables = new ArrayList<Drawable>(10);
which i want to sort alphabetically.
For this i created a TreeMap:
Map<List<String>, List<Drawable>> myMapToSort = new TreeMap<List<String>, List<Drawable>>();
myMapToSort.put(names, drawables);
First two Question
Is the map now sorted in lexicographical order? Or do i Need to do something additional?
After i have sorted them, if they are yet, i want to split them back again to List<String> and List<Drawable>. And i tried like this:
List<String> sortedNames = new ArrayList<String>(myMapToSort.keySet());
Of course it doesn't work because myMapToSort.keySet() Returns a Set and not List.
And List doesn't have an Constructor for a Set.
So how can i accomplish that and what i'm misunderstanding?
Any help is appreciated. Thanks in advance!
I figured it out by my own.
The key was to create a TreeMap with not two list but two single Objects:
Map<String, Drawable> myTreeMap = new TreeMap<String, Drawable>;
Then add the Items from the Arraylists one by one to the Map:
for(int i = 0; i<names.size(); i++) {
myTreeMap.put(names.get(i), drawables.get(i));
}
Now the Map is automatically sorted Lexicographical in relation with the Drawables.
That means Names and Drawables are sorted in lexicographical order.
If you want to retrieve the keys and the values and put them back in seperate ArrayLists simply type:
List <String> mySortedNames = new ArrayList<String>(myTreeMap.keySet());
List <Drawables> mySortedDrawables = new ArrayList<Drawables>(myTreeMap.values());
That's it. ;)
You can use SortedSet (or SortedList) to have sorted elements. The elements are ordered using their natural ordering, or by a Comparator typically provided at sorted set creation time.
For splitting a Map in two lists :
List<String> sortedNames = new ArrayList<String>();
List<Drawable> drawables = new ArrayList<Drawable>();
for (Map.Entry<String, Drawable> entry : map.entrySet())
{
sortedNames.add(entry.getKey()
drawables.add(entry.getValue());
}
Related
I have a hashmap which have same value but different key.I want to sort them how this will possible?
Image of this Hashmap is below
HashMap Image
public static HashMap<String,Integer> entry = new HashMap<>();
Use TreeMap for sorting by key
Use below code for sorting by value:
private static HashMap sortByValues(HashMap map) {
List list = new LinkedList(map.entrySet());
// Defined Custom Comparator here
Collections.sort(list, new Comparator() {
public int compare(Object o1, Object o2) {
return ((Comparable) ((Map.Entry) (o1)).getValue())
.compareTo(((Map.Entry) (o2)).getValue());
}
});
// Here I am copying the sorted list in HashMap
// using LinkedHashMap to preserve the insertion order
HashMap sortedHashMap = new LinkedHashMap();
for (Iterator it = list.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
sortedHashMap.put(entry.getKey(), entry.getValue());
}
return sortedHashMap;
}
Please check here for details.
Here some good example for sorting HashMap in Java by Keys and Values.
HashMap is not meant to keep entries in sorted order, but if you have to sort HashMap based upon keys or values, you can do that in Java. Sorting HashMap on keys is quite easy, all you need to do is to create a TreeMap by copying entries from HashMap. TreeMap is an implementation of SortedMap and keeps keys in their natural order or a custom order specified by Comparator provided while creating TreeMap. This means you can process entries of HashMap in a sorted order but you cannot pass a HashMap containing mappings in a specific order, this is just not possible because HashMap doesn't guarantee any ordering. On other hand, sorting HashMap by values is rather complex because there is no direct method to support that operation. You need to write code for that. In order to sort HashMap by values you can first create a Comparator, which can compare two entries based on values. Then get the Set of entries from Map, convert Set to List and use Collections.sort(List) method to sort your list of entries by values by passing your customized value comparator. This is similar of how you sort an ArrayList in Java. Half of the job is done by now. Now create a new LinkedHashMap and add sorted entries into that. Since LinkedHashMap guarantees insertion order of mappings, you will finally have a Map where contents are sorted by values.
Detailed information over here:
https://www.java67.com/2015/01/how-to-sort-hashmap-in-java-based-on.html
I am displaying list of check-boxes in horizontal RecyclerView.
It display values such as {"Rd" , "Gr" , "Yl"} but when user selects any of this value it should return {"RED" , "GREEN" , "YELLOW")
How can I bind these two value that show and return differently?
I am taking display values from R.string-arry
I created another string-array of actual values, and when user checked any of checkboxes I get that ID and replaced it with actual values.
For e.g. If user has selected "Gr" I get ID=1 then replaced with actual string-array
But this only works when code-color and original-color are in order. In my app I sometimes use Red,green,blue or sometimes green,yellow,blue. So, this won't help me.
From what I understood, you need a mapping between GR and Green, RD and Red etc.
You can try using a Hashmap.
HashMap<String,String> colourMap = new HashMap<>();
colourMap.put("GR","GREEN");
colourMap.put("RD","RED");
And then you can retrieve the respective value for your colour code:
String colour = colourMap.get("GR");
You can use a HashMap which will bind the two arrays as key value pair
public HashMap<String,String> bindColors() {
HashMap<String,String> map = new HashMap<>();
int length = orginalColors.length;
for (int i = 0; i < length; i++) {
map.put(orginalColors[i], codeColors[i]);
}
return map;
}
And for getting the Colors in code.
HashMap<String, String> keyPair = bindColors();
orginalColorsNewArray = keyPair.keySet().toArray(new String[keyPair.keySet().size()]);
codeColorsNewArray = keyPair.values().toArray(new String[keyPair.values().size()]);
or use .get() function
keyPair.get("YELLOW")
Now it will be easier for you to access the codes by id/position
Hope this helps.
I'm trying to implement an expandable listview with data coming from a database. I've already tried having the data added within the codes and it works so I'm now trying to have dynamic data from the database populate the listview.
The data is grouped in two, the main category and the member. For example if the main category is fruit, it's members may include mango, avocado, apples, etc. If animals, it may have horses, eagle, shark. The data always comes in pairs such as Animal, Horses; Animal, Eagle; Fruit, Apples. The expandable listview should appear as:
Animal
-- Horses
-- Eagle
Fruit
-- Apples
My code below can already determine the main group so the headers already display the main groupings of Fruit and Animal. By using
group_member.put(family_name, member_name);
I linked the member to the main category. My problem now is how to code for the iteration to group the members to the main category. So far I've already tried using iterator based on the sample codes given here in stackoverflow and from other sites however only the last elements of each group is display. I've also tried using the for-each loop bur still no success.
String json = jsonParser.makeHttpRequest(URL_COMPONENTS, "POST", params);
JSONArray components = null;
ArrayList<HashMap<String, String>> componentList;
List<String> main_group = new ArrayList<String>();
HashMap<String, String> group_member = new HashMap<String, String>();
try {
components = new JSONArray(json);
if (components != null) {
for (int i = 0; i < components.length(); i++) {
JSONObject c = components.getJSONObject(i);
String family_name = c.getString(TAG_FAMILY_NAME);
String member_name = c.getString(TAG_MEMBER_NAME);
main_group.add(family_name);
group_member.put(family_name, member_name);
if (!listDataHeader.contains(main_group))
listDataHeader.add(main_group);
componentList.add(group_member);
}
}
}
Please help. Thanks in advance!
If you're using HashMap you can't have a key more than once in your list. Each key must be unique.
This could be a solution:
HashMap<String, ArrayList<String>> group_member = new HashMap<String, ArrayList<String>>();
... using the Hashmap as a directory and the key is returning an Arraylist of the family members.
Im using hashmap and arraylist...
How to sort the arraylist ? eg) In hashmap values are in order like one,two,three,four,five
but i stored these values in arraylist the order changed like three,one,five,two,four
In my code groupList,gnamelist and newList are all arraylist...
In print sts PLACES are in correct order but while print on NEWLIST PLACES the order changed
How to sort this in order?
My code
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_PLACE, gname);
map.put(TAG_HOTEL,lname);
// adding HashList to ArrayList
groupList.add(map);
gnamelist.add(gname);
System.out.println("PLACES" + gnamelist);
List<String> newList = new ArrayList<String>(new LinkedHashSet<String>(gnamelist));
Collections.sort(newList,Collections.reverseOrder());
System.out.println("NEWLIST PLACES" + newList);
HashSet will store elements in an unordered fashion, and is likely the culprit of your element reordering.
List<String> newList = new ArrayList<String>(new HashSet<String>(gnamelist));
Also consider using LinkedHashMap/LinkedHashSet, which preserves the ordering of elements added to it.
Alternatively try the following:
gnamelist.add(gname);
System.out.println("PLACES" + gnamelist);
List<String> newList = new ArrayList<String>();
newList.addAll(gnamelist);
Try
Collections.sort(newList);
Edit:
If you want to sort in reverse use this
Collections.sort(newList,Collections.reverseOrder());
Important:
if you want to preserve insertion order, you need to use TreeSet instead of HashSet as HashSet doesn't preserve insertion order
I need to be able to create and delete groups in my expandableListAdapter dynamically. I have looked through all that I can find and am stuck. I do not need specific code, but just to be pointed in the right direction.
First, we need some data structures (keep a reference to them for later use).
headerData = new ArrayList<HashMap<String, String>>();
childData = new ArrayList<ArrayList<HashMap<String, Object>>>();
headerData is the list of groups - HashMap is used since each group can have multiple display values, each of which is mapped onto the layout by key.
childData is the list of items belonging to each group. Its a list of lists, each containing HashMaps - similar to the groups, each child can have multiple display values which are mapped by key.
We supply these datastructures to our ExpandableListAdapter on creation. We're also telling the adapter how the display values should be mapped; in this example both groups and children have two display values, keys "name" and "fields" which are mapped onto text1 and text2 in the supplied layouts.
adapter = new SimpleExpandableListAdapter( SearchLogs.this,
headerData, R.layout.customlayout_group,
new String[] { "name", "fields" }, new int[] { R.id.text1, R.id.text2 },
childData, R.layout.customlayout_child,
new String[] { "name", "fields" }, new int[] { R.id.text1, R.id.text2 } );
setListAdapter(adapter); // assuming you are using ExpandableListActivity
Up to this point we have an empty ExpandableList. We can populate it dynamically (using an AsyncTask for example) by creating HashMaps that supply values for keys we are using and then adding them to our lists.
For example, to add a group with a couple children we might ...
HashMap<String, String> group = new HashMap<String, String>();
group.put("name", "whatever...");
group.put("fields", "...");
ArrayList<HashMap<String, Object>> groupChildren = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> child1 = new HashMap<String, Object>();
child1.put("name", "child name");
child1.put("fields", "...");
HashMap<String, Object> child2 = new HashMap<String, Object>();
child2.put("name", "another child");
groupChildren.add(child1);
groupChildren.add(child2);
headerData.add(group);
childData.add(groupChildren);
Each HashMap in headerData corresponds (by order) to an ArrayList in childData, which contains additional HashMaps that define the actual children. SO even if you are adding an empty group, remember to add a corresponding (empty) ArrayList to childData.
We just added a group to the end of the list - we can just as easily insert as long as we are mindful to insert into the same position in both headerData and childData. Removing groups is the same - be certain to remove from the same position of both headerData and childData.
Finally, notify the adapter that the data has changed, which will cause the List to refresh. If using an AsyncTask, this must be done outside of doInBackground (use onProgressUpdate in this case).
adapter.notifyDataSetChanged();
I hope this helps you move in the right direction. ExpandableList, in terms of how data is stored, is definitely one of the more complicated Android views.