views:

127

answers:

3

I've only started learning Java about 3 months ago and this is my first post here, so please bear with me.

I have multiple ArrayLists built from parsed XML that are directly related to each other in order. The arrays are later put into a single mapped ArrayList (groupData) to be read with a SimpleAdapter which creates the list in the Android GUI.

What I want to do is sort the list in alphabetical order based on one array (arr_title) and the other arrays stay in synchronized order to it. It doesn't matter where the sorting happens as long as the final displayed list is sorted. I expect it would be best to sort the mapped array once it's built. The simpler or easier to understand the code the better, but don't want the sorting to go very slow either. I have about 140 objects per array, but that could expand considering the XML is pulled from the web.

I've spent hours searching Google and tried a number of things with little progress. Collections.sort(arr_title) will sort the one array as I want it, but then the other arrays don't match up and doing the same thing to the other arrays obviously just sorts them individually as I don't want. I've noticed mention of using the TreeMap type and Comparator for similar sorting, but couldn't figure out how to use them in this case probably because the examples didn't provide a big enough picture for me to understand.

The sample below is where most of the stuff happens after the separate arrays are created.

List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
Map<String, String> group;

int item = 0;
do {
    group = new HashMap<String, String>();
    group.put("title", arr_title.get(item));
    group.put("desc", arr_desc.get(item));
    group.put("num", Integer.toString(arr_num.get(item)));
    groupData.add(group);
    item++;
} while (item < arr_num.size());

SimpleAdapter adapter = new SimpleAdapter(this, groupData, android.R.layout.simple_list_item_2, new String[] {"title", "desc", "num"}, new int[]{android.R.id.text1, android.R.id.text2});
setListAdapter(adapter);
A: 

It sounds to me like you've make a classic beginner mistake (for which you can be forgiven): not thinking enough in terms of objects.

Java's an object-oriented language. It sounds to me like your multiple lists of related items should really be a single List of objects that each contain their set of the items you're currently putting into multiple lists. Then you can sort that List of Objects using a Comparator any way you wish. All the related attributes are nicely encapsulated inside their object, where they belong. They stay together no matter how you sort them.

Objects are all about encapsulation and information hiding.

duffymo
+1  A: 

Welcome to SO.

First of all, there are Java conventions to name the variables. Have a look at the Naming conventions

Secondly, Java is an Object Oriented Language, so you have to change your mind a little bit about how you approach problems.

In this particular case, you want all the data scattered among 3 arrays to be together. Well, create a class for it.

public class Data implements Comparable{
 private String title;
 private String desc;
 private int num;
 public Data(String title, String desc, int num){
  //set the private fields here
}
//You may want to write some setters and getters here for individual fields.

public int compareTo(Object o){
//here you compare an item with other item. Remember to cast the object o to Data.
// Read http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Comparable.html to know what to return
}

}

And then in your main class:

int item = 0;
do {
    Data group = new Data(arr_title.get(item),arr_desc.get(item),arr_num.get(item);
    groupData.add(group);
    item++;
} while (item < arr_num.size());
Collections.sort(groupData);

Last but not least, there are better ways to iterate through a set in Java. Read about Iterators. It's a much secure and cleaner way to go through an array or a set.

pakore
While I have very basic knowledge of several languages, I consider Java to be the first language I've learned, so I'm not really taking much as far as skills from another language into Java. I remember touching on the object-oriented topic when I first started getting into Java, but I guess I didn't spend enough time on it to fully understand it or build the habit of using it properly. I guess that's a typical problem with going at it alone instead of taking classes.I'll give your example a spin and let you know how it goes. Thanks!
Pilot_51
Unfortunately I still seem to be having trouble.There are a number of warnings and at first were some errors, but after changing the first line to List<Data> groupData = new ArrayList<Data>();, removing Map<String, String> group;, then casting groupData in SimpleAdapter to (List<? extends Map<String, ?>>) as Eclipse suggested, I managed to get rid of the errors and compile, but I get a ClassCastException at runtime. It appears to be caused by the type of list that the SimpleAdapter accepts. I'll keep crunching on this, but any more tips would be appreciated.
Pilot_51
Yeah that's normal because Java is a strict typed language. You changed the type of the data, so it complains :).What you have to do now is modify SimpleAdapter to receive a List of Data (List<Data>) instead of the old groupData.
pakore
Sorry if I'm not responding quickly, most of my time is spent on other projects where this isn't an issue. Your example is working and I created a CustomAdapter which works with the new list and appears almost identical in the GUI to the SimpleAdapter. The only thing I have yet to get working is still the sorting. I suppose (please let me know if it's not the case) I just need to study up on usage of Comparable and probably Iterator and once I have it figured out this should hopefully be solved.
Pilot_51
For sorting, you need to implement the `compareTo` method in pakore's example. He has mentioned a link to the details. In a nutshell, in the `compareTo` method you tell java how you want to cpmpare two of your `Data` objects - how you define whether `data1 < data2` (or `>` or `==`). In this case you probably want to compare the `title` or `num` to decide how one `data` object stands in comparison to another. So typically the compare method would contain `return ((Data)o).title.compareTo(this.title);` (or similarly with `num`)
Nivas
A: 

I finally figured it out! Thanks to a bigger project coming across a similar issue essentially forcing me to get this solved. Everything outside this sample is mostly the same as it was at the original post apart from some changed variable names. I'm not sure if this is the best way to do it, but it gets the job done at a very acceptable speed and I can actually understand how it works.

ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
// Put separated item details in a HashMap for each item,
// then insert it in sorted order to list.
for(int n = 0; n < arrayTitle.size(); n++) {
    HashMap<String, String> item = new HashMap<String, String>();
    item.put("title", arrayTitle.get(n));
    item.put("desc", arrayDesc.get(n));     
    try {
        int c, i = 0;
        do {
            // Compare new title with titles existing in list 
            // from beginning to end or until title is found that it goes before.
            c = arrayTitle.get(n).compareTo(list.get(i).get("title"));
            i++;
        } while (c > 0 & i < list.size());
        i--;
        if(c > 0) {
            // New item goes after all others currently in list.
            list.add(item);
        } else if (c < 0) {
            // New item goes before an item already in list.
            list.add(i, item);
        }
    } catch (Exception e) {
        // If nothing in list to compare with, add first item.
        list.add(item);
    }
}       
SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, new String[] {"title", "desc"}, new int[]{android.R.id.text1, android.R.id.text2});
setListAdapter(adapter);
Pilot_51
Perhaps for later, but do look at the `Collections.sort` and `comparable` - with these you can do what you have done without writing the code for sorting. You just hint java *how to sort* (via `compareTo`) and Collections.sort does the sorting for you. You would not need your for and while loops.
Nivas
That's what I was trying to do before, but I must've been doing something wrong. I didn't understand how to get it working with anything other than ArrayList<String> and to get it working with other types seemed to require more coding (which I failed to understand) than I did here. I'll accept a working example if you want to give it to me, but since I'm satisfied with what I have, I currently don't care to put more effort into figuring out how to make it more efficient. I'm sure I'll want to optimize it further down the road.
Pilot_51