Java - Create sublist from a list based on suffix

1.1k views Asked by At

I'm trying to create sublists from a list based on the suffix.

public class Test {

    public static void main(String args[]) {
        List<List<String>> subList = new ArrayList<List<String>>();

        List<String> myList = new ArrayList<String>();
        myList.add("Text_1");
        myList.add("XYZ_3");
        myList.add("ABC_1");
        myList.add("Text_2");
        myList.add("Text_3");
        myList.add("XYZ_1");
        myList.add("XYZ_2");
        myList.add("ABC_2");

        for (String item : myList) {
            List<String> tempList = new ArrayList<String>();
            String suffix = item.substring(item.lastIndexOf("_"));
            tempList.add(item);
            for (String value : myList) {
                if (value.endsWith(suffix) && !tempList.contains(value)) {
                    tempList.add(value);
                }
            }
            System.out.println(tempList);
        }
    }
}

I'm expecting like below

// Text_1, ABC_1, XYZ_1
// Text_2, ABC_2, XYZ_2
// Text_3, XYZ_3

But the actual is

[Text_1, ABC_1, XYZ_1]
[XYZ_3, Text_3]
[ABC_1, Text_1, XYZ_1]
[Text_2, XYZ_2, ABC_2]
[Text_3, XYZ_3]
[XYZ_1, Text_1, ABC_1]
[XYZ_2, Text_2, ABC_2]
[ABC_2, Text_2, XYZ_2]

Any help is appreciated. Thanks

5

There are 5 answers

0
Sharon Ben Asher On BEST ANSWER

There are several problems with your code:

1) you build the tempList on every item, so while the result are correct, you will see them for every item in myList. you need to "remember" each suffix you process so that you won't process it again. a HashMap will do the job

2) if you want tempList to have uniqe values, use Set

here is the complete solution

    public static void main(String args[]) {
    Map<String, Set<String>> subList = new HashMap<>();

      List<String> myList = new ArrayList<String>();
      myList.add("Text_1");
      myList.add("XYZ_3");
      myList.add("ABC_1");
      myList.add("Text_2");
      myList.add("Text_3");
      myList.add("XYZ_1");
      myList.add("XYZ_2");
      myList.add("ABC_2");

      for (String item : myList) {
          String suffix = item.substring(item.lastIndexOf("_"));
          if (subList.containsKey(suffix))  continue;
          Set<String> tempSet = new HashSet<String>();
          tempSet.add(item);
          for (String value : myList) {
              if (value.endsWith(suffix)) {
                  tempSet.add(value);
              }
          }
          subList.put(suffix, tempSet);
      }
      System.out.println(subList);
  }

output:

{_1=[Text_1, ABC_1, XYZ_1], _2=[ABC_2, XYZ_2, Text_2], _3=[XYZ_3, Text_3]}
0
Aston Ray On

Have a look at this ,i am using a map with suffix values as a key and List of common types as a value .

List<String> myList = new ArrayList<String>();
    myList.add("Text_1");
    myList.add("XYZ_3");
    myList.add("ABC_1");
    myList.add("Text_2");
    myList.add("Text_3");
    myList.add("XYZ_1");
    myList.add("XYZ_2");
    myList.add("ABC_2");
    Map<String, List<String>> map=new HashMap<String,List<String>>();
    for(String str:myList){
        String[] arryStr=str.split("_");
        if(! map.containsKey(arryStr[1])){
            List<String> tmpList=new ArrayList<String>();
            tmpList.add(str);
            map.put(arryStr[1],tmpList);
        }else{
            List<String> existingList=map.get(arryStr[1]);
            existingList.add(str);
        }

    }
0
chengpohi On

The issues as @sharonbn, but also you can update the value when you get a suffix everytime.

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

List<String> myList = new ArrayList<String>();
myList.add("Text_1");
myList.add("XYZ_3");
myList.add("ABC_1");
myList.add("Text_2");
myList.add("Text_3");
myList.add("XYZ_1");
myList.add("XYZ_2");
myList.add("ABC_2");

for (int i = 0; i < myList.size(); i++) {
    String item = myList.get(i);
    List<String> tempList = new ArrayList<String>();
    int location = item.lastIndexOf("_");
    if (location < 0) continue;
    String suffix = item.substring(location);
    tempList.add(item);
    for (int j = i + 1; j < myList.size(); j++) {
        String value = myList.get(j);
        if (value.endsWith(suffix) && !tempList.contains(value)) {
            tempList.add(value);
            myList.set(j, "-------");
        }
    }
    System.out.println(tempList);
}
0
almightyGOSU On

Try using a TreeMap?

import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;

public class QuickTester {

    public static void main(String[] args) {

        List<String> myList = new ArrayList<String>();
        myList.add("Text_1");
        myList.add("XYZ_3");
        myList.add("ABC_1");
        myList.add("Text_2");
        myList.add("Text_3");
        myList.add("XYZ_1");
        myList.add("XYZ_2");
        myList.add("ABC_2");

        TreeMap <String, ArrayList<String>> map = new TreeMap<>();

        for (String item : myList) {

            // contents[0] is value, contents[1] is suffix
            String [] contents = item.split("_");

            if(!map.containsKey(contents[1])) {
                ArrayList<String> values = new ArrayList<>();
                values.add(contents[0]);
                map.put(contents[1], values);
            }
            else {
                map.get(contents[1]).add(contents[0]);
            }
        }

        for(String key : map.keySet()) {
            System.out.println("Key: " + key);
            System.out.print("Values: ");
            for(String value : map.get(key)) {
                System.out.print(value + " ");
            }
            System.out.println();
        }
    }
}

Output:

Key: 1
Values: Text ABC XYZ 
Key: 2
Values: Text XYZ ABC 
Key: 3
Values: XYZ Text 
0
dijkstra On

You can use a list for adding seen suffixes. If this list contains the suffix, you do nothing.

    List<String> seenSuffixes = new ArrayList<String>();
    for (String item : myList) {

        String suffix = item.substring(item.lastIndexOf("_"));
        if(!seenSuffixes.contains(suffix)){
             seenSuffixes.add(suffix);
             List<String> tempList = new ArrayList<String>();
             tempList.add(item);
             for (String value : myList) {
                  if (value.endsWith(suffix) && !tempList.contains(value)) {
                       tempList.add(value);
                  }
             }
             System.out.println(tempList);
           }

        }