1

I have a string array with values

List<String> list = new ArrayList<String>();
list = {'name1','10','name2','2','name3','15','name4','7'}  

I want to sort this list and the output should be

list = {'name3','15','name1','10','name4','7','name2','2'}

How can I achieve this?

jzd
  • 23,473
  • 9
  • 54
  • 76
Jones
  • 11
  • 2

9 Answers9

6

You too seem to be living in object denial. Using a list for this data (or at least a list of strings) is simply using the wrong data structure.

You obviously have some kind of key-value or value-value pair in that list, but have not made that fact explicit. This means that any manipulation to that data structure will be complex and cumbersome and all the default-features of the language or libraries will not do what you expect.

A better solution would be to store the name and numeric value (age?) in some object and keep a list of such objects.

Then that list can be sorted by either implementing Comparable in that class or by providing a Comparator.

Community
  • 1
  • 1
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
1

Create your class

package org.life.java.stackoverflow.questions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

//class for your data representation
class Data{
    private int no;
    private String data;

    public String getDaa() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Data(int no, String data) {
        this.no = no;
        this.data = data;
    }

    public Data() {
    }


    @Override
    public String toString() {
        return "SortingDemo{" + "no=" + no + "data=" + data + '}';
    }

}

Create comparator and sort the list

public class SortingDemo {    

    public static void main(String[] args) {
    List<Data> listOfData = new ArrayList<Data>();
    listOfData.add(new Data(1,"DataFor one"));
    listOfData.add(new Data(15,"DataFor 15"));
    listOfData.add(new Data(10,"DataFor 10"));
    //defincation of Comparator for your case , which compares object based on the `no`
    Collections.sort(listOfData,new Comparator<Data>() {

            @Override
            public int compare(Data o1, Data o2) {
                return o2.getNo() - o1.getNo();
            }
        });
    }
}
jmj
  • 237,923
  • 42
  • 401
  • 438
1

First you need to put your name and value combination into one object instead of sequential array locations.

Then make the object implement Comparable.

Lastly put the objects in a List and use Collections.sort to sort the list.

jzd
  • 23,473
  • 9
  • 54
  • 76
0

Have a look at TreeMap. I think thats what your looking for.

kukudas
  • 4,834
  • 5
  • 44
  • 65
0

Assuming that every namex (where x = 1, 2, 3, ...) is unique, than you can solve your problem by using a SortedMap

public static void main(String[] args) {
    SortedMap<String, Integer> sortedMap = 
        new TreeMap<String, Integer>();
    sortedMap.put("name1", Integer.valueOf(10));
    sortedMap.put("name2", Integer.valueOf(2));
    sortedMap.put("name3", Integer.valueOf(15));
    sortedMap.put("name4", Integer.valueOf(7));
    for (String key : sortedMap.keySet())
        System.out.println(key + " - " + sortedMap.get(key));
}
MarcoS
  • 13,386
  • 7
  • 42
  • 63
0
list = {'name3','15','name1','10','name4','7','name2','2'}

it is a definitely a map what you need. Name and key ordered by key in descending order. You will not be able to sort in descending order if you do not store your keys as int or at least represent '7' as ' 7' or '07' and '2' as ' 2' or '02'.

Costis Aivalis
  • 13,680
  • 3
  • 46
  • 47
0

I would recommend that you use a Map instead of a list and then you can do something like this:

 public static void main(String[] args) throws Exception{
         HashMap<String, Integer> map = new HashMap<String, Integer>();
         map.put("name10", 2);
         map.put("name20", 1);
         Map<String, Integer> sortedMap = sortByValue(map);

         for (String key : sortedMap.keySet()) {
                System.out.println("key/value: " + key + "/"+sortedMap.get(key));
            }
        }

    static Map sortByValue(Map map) {
         LinkedList list = new LinkedList(map.entrySet());
         Collections.sort(list, new Comparator() {
              public int compare(Object o1, Object o2) {
                   return ((Comparable) ((Map.Entry) (o1)).getValue())
                  .compareTo(((Map.Entry) (o2)).getValue());
              }
         });

        Map result = new LinkedHashMap();
        for (Iterator it = list.iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry)it.next();
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    } 

Sort a Map<Key, Value> by values (Java)

Community
  • 1
  • 1
0

Challenge accepted:

import java.util.*;

class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>(Arrays.asList("name1", "10",
                                                                "name2", "2",
                                                                "name3", "15",
                                                                "name4", "7"));

        List<NameNumPair> nps = new ArrayList<NameNumPair>();
        for (int i = 0; i < list.size(); i += 2)
            nps.add(new NameNumPair(list.get(i),
                    Integer.parseInt(list.get(i+1))));

        Collections.sort(nps);

        List<String> sortedList = new ArrayList<String>();
        for (NameNumPair np : nps) {
            sortedList.add(np.name);
            sortedList.add(np.num.toString());
        }

        System.out.println(sortedList);
    }

}

class NameNumPair implements Comparable<NameNumPair> {
    String name;
    Integer num;

    public NameNumPair(String name, int num) {
        this.name = name;
        this.num = num;
    }

    @Override
    public int compareTo(NameNumPair o) {
        return o.num.compareTo(num);
    }
}

Output:

[name3, 15, name1, 10, name4, 7, name2, 2]
aioobe
  • 413,195
  • 112
  • 811
  • 826
0

As several people have said, you probably don't want to do that.

But: if you do want to do it, as an exercise in Java object wrapping, with complete disregard for efficiency and good programming practice, here's a way that stays as close as possible to what you wrote in the question.

import java.util.*;

public class CrazySort {
    public static void main(String[] args) {
        List<String> list = Arrays.asList(new String[] {"name1","10","name2","2","name3","15","name4","7"});
        crazySort(list);
        System.out.println(list);
    }

    private static class StringPair implements Comparable<StringPair> {
        String s1, s2;
        StringPair(String p1, String p2) { s1 = p1; s2 = p2; }
        public int compareTo(StringPair o) { return Integer.parseInt(o.s2) - Integer.parseInt(s2); }
    }

    static void crazySort(final List<String> list) {
        List<StringPair> wrapper = new AbstractList<StringPair>() {
            public StringPair get(int i) { return new StringPair(list.get(i*2), list.get(i*2+1)); }
            public StringPair set(int i, StringPair p) {
                StringPair r = get(i); 
                list.set(i*2, p.s1); 
                list.set(i*2+1, p.s2); 
                return r;
            }
            public int size() { return list.size() / 2; }
        };
        Collections.sort(wrapper);
    }
}
njlarsson
  • 2,128
  • 1
  • 18
  • 27