4

I have two ArrayLists.

  • The first contains a group of words with capitalization and punctuation.

  • The other contains this same group of words, but with the capitalization and punctuation removed.

.

ArrayList1 ..... ArrayList2

MURDER! ........ murder

It's ........... its

Hello .......... hello

Yes-Man ........ yesman

ON ............. on

The second array has all the words alphabetized and all the letters in each word alphabetized. It looks something like this:

aemnsy
demrru
ehllo
ist
no

I want to make it so that when I arrange the words in ArrayList two into alphabetical order, all the words from ArrayList one follow suite:

ArrayList1 ..... ArrayList2

Yes-Man ........ aemnsy

MURDER! ........ demrru

Hello .......... ehllo

It's ........... ist

ON ............. no

I tried to make a loop with a for statement or two, but it ended up not working and became very long. How do I do this? How do I do this efficiently?

7
  • 6
    It sounds like you want to use a Map rather than two Lists Commented Mar 14, 2013 at 3:14
  • 1
    If you can, use a TreeMap<String, String> where the key is the String from ArrayList2 and the value is from ArrayList1. Commented Mar 14, 2013 at 3:29
  • What's wrong with the two Collections.sort calls? Commented Mar 14, 2013 at 3:29
  • @Thihara are you sure of your comment? Have you read the question? Commented Mar 14, 2013 at 3:29
  • Oops, at first glance I thought he just needs to sort the two array lists... On second read I see why the map is the answer... Commented Mar 14, 2013 at 4:38

5 Answers 5

5

Here is a function to sort multiple lists based on a single 'key' list. The lists do not need to be the same type, here the key list is type String and it's used to sort a String, Integer, and Double list (Ideone Example):

List<String> key = Arrays.asList("demrru", "ist", "ehllo", "aemnsy", "no");
List<String> list1 = Arrays.asList("MURDER!","It's", "Hello","Yes-Man", "ON");
List<Integer> list2 = Arrays.asList(2, 4, 3, 1, 5);            // Also use Integer type 
List<Double>  list3 = Arrays.asList(0.2, 0.4, 0.3, 0.1, 0.5);  // or Double type

// Sort all lists (excluding the key)
keySort(key, list1, list2, list3);

// Sort all lists (including the key)
keySort(key, key, list1, list2, list3);

Output:

// Sorted by key:
[Yes-Man, MURDER!, Hello, It's, ON]
[aemnsy, demrru, ehllo, ist, no]
[1, 2, 3, 4, 5]
[0.1, 0.2, 0.3, 0.4, 0.5]

Sort Function

An Ideone Example can be found here which includes validation of parameters and a test case.

public static <T extends Comparable<T>> void keySort(
                                        final List<T> key, List<?>... lists){
    // Create a List of indices
    List<Integer> indices = new ArrayList<Integer>();
    for(int i = 0; i < key.size(); i++)
        indices.add(i);

    // Sort the indices list based on the key
    Collections.sort(indices, new Comparator<Integer>(){
        @Override public int compare(Integer i, Integer j) {
            return key.get(i).compareTo(key.get(j));
        }
    });

    // Create a mapping that allows sorting of the List by N swaps.
    Map<Integer,Integer> swapMap = new HashMap<Integer, Integer>(indices.size());

    // Only swaps can be used b/c we cannot create a new List of type <?>
    for(int i = 0; i < indices.size(); i++){
        int k = indices.get(i);
        while(swapMap.containsKey(k))
            k = swapMap.get(k);

        swapMap.put(i, k);
    }

    // for each list, swap elements to sort according to key list
    for(Map.Entry<Integer, Integer> e : swapMap.entrySet())
        for(List<?> list : lists)
            Collections.swap(list, e.getKey(), e.getValue());
}
Sign up to request clarification or add additional context in comments.

1 Comment

I tried that the first list is not sorted and the second one is not synced with first one!!
4

First Way - I use map whose key is from arrayList2 and value is from arrayList1. Putting data to map is up to you. After sorting arrayList2, I get its value from map.

  List<String> arrList1 = new ArrayList<String>();

            arrList1.add("MURDER!");
            arrList1.add("It's");
            arrList1.add("Hello");
            arrList1.add("Yes-Man");
            arrList1.add("ON");

            List<String> arrList2 = new ArrayList<String>();
            arrList2.add("demrru");
            arrList2.add("aemnsy");
            arrList2.add("ist");
            arrList2.add("ehllo");
            arrList2.add("no"); 

            Map<String, String> map1 = new HashMap<String, String>();
            map1.put("aemnsy", "Yes-Man");
            map1.put("demrru", "MURDER!");
            map1.put("ehllo", "Hello");
            map1.put("ist", "It's");
            map1.put("no", "ON");

            Collections.sort(arrList2);

            for (String s : arrList2){
                System.out.println(s + "..........." + map1.get(s));
            }

Second Way - Another way is you can use only TreeMap which is already sorted instead of two ArrayList.

Map<String, String> map2 = new TreeMap<String, String>();
            map2.put("ehllo", "Hello");
            map2.put("aemnsy", "Yes-Man");
            map2.put("demrru", "MURDER!");
            map2.put("no", "ON");
            map2.put("ist", "It's");

            for (Map.Entry<String, String> entry : map2.entrySet())
            {
                System.out.println(entry.getKey() + "/" + entry.getValue());
            }

Third way - only using 2 ArrayList, but we have to write sorting method by our own. Have you notice that your 2 ArrayList elements such as aemnsy from arrayList2 and Yes-Man from arrayList1 have same index? I use that point.

  selectionSort1(arrList2, arrList1);

    for(int i = 0; i < arrList1.size(); i++){
        System.out.println(arrList2.get(i) + "---" + arrList1.get(i));
    }

   public static void selectionSort1(List<String> x, List<String> y) {
    for (int i=0; i<x.size()-1; i++) {
        for (int j=i+1; j<x.size(); j++) {
            if (x.get(i).compareTo(x.get(j)) > 0) {
                //... Exchange elements in first array
                String temp = x.get(i);
                x.set(i, x.get(j));
                x.set(j, temp);

                //... Exchange elements in second array
                temp = y.get(i);
                y.set(i, y.get(j));
                y.set(j, temp);
            }
        }
    }
}

10 Comments

I would very much prefer to use only a Map, but sadly that is not the objective of the exercise. However using a map for two arraylists... Well let me play around with this for a bit and I'll get back to you.
If you're going to use a TreeMap it would be better to declare it as TreeMap<String,String> map2 or NavigableMap<String, String> in order to use all the methods in the class/interface (check my comment).
In an attempt to use the map, I discovered that the map was not retaining the original values for List1, but was instead replacing them with only one of the values of the words that were anagrams of each other. Where the other words went I do not know.
@RyanTibbetts it looks that you have never used a Map before. By the way, do you really need two synchronized List<String> backed up with ArrayList<String>? This looks like a design flaw since you can have a AnagramWord class with private String anagram and private String word attributes in it and a simple List<AnagramWord> that you can sort however you want by just providing a Comparator<AnagramWord>.
Your third way make my eyes bleed. With it, you're just reinventing the wheel using a String[] instead of List<String> ls = new ArrayList<String> and even worse: using a selection sort instead of Collections.sort(somethingThatImplementList) that uses an optimized MergeSort.
|
0

A Quick Answer.

public class MapAlph {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<String, String>();
        String txt = "Murde!r!";
        ArrayList<Character> alph = new ArrayList<Character>();
        for (int i = 0; i < txt.length(); i++)
            if (Character.isLetter(txt.charAt(i)))
                alph.add(txt.charAt(i));

        Collections.sort(alph);
        Collections.reverse(alph);
        String val = "";
        for (Character c : alph)
            val += c;

        map.put(txt, val);
        System.out.print(txt + " ........ " + map.get(txt));
    }
}

1 Comment

Did you just have that sitting around or something?
0

You can make use of TreeMap, if you wish.

Map<String, String> sortedMap = new TreeMap<String, String>();
sortedMap.put("demrru", "MURDER!");
sortedMap.put("ist", "It's");
sortedMap.put("aemnsy", "Yes-Man");
sortedMap.put("ehllo", "Hello");
sortedMap.put("no", "ON");

Comments

-1

You can try this:

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;


public class SortService {

    public static void main(String[] args) {
        Map<String, String> originalMap = new HashMap<String, String>();
        originalMap.put("aemnsy", "Yes-Man");
        originalMap.put("demrru", "MURDER!");
        originalMap.put("ehllo", "Hello");
        originalMap.put("ist", "It's");
        originalMap.put("no", "ON");

        Map<String, String> sortedMap = new TreeMap<String, String>(originalMap);
        System.out.println(sortedMap);
    }

}

output:

{aemnsy=Yes-Man, demrru=MURDER!, ehllo=Hello, ist=It's, no=ON}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.