简体   繁体   中英

How to put values from ArrayList of Arraylist with same value in hashmap

I have an ArrayList of ArrayList of String which with below values:

{0=>[name:'data1',phone:'123',shipping:'location1'],  
1=>[name:'data1',phone:'456',shipping:'location2'],  
2=>[name:'data1',phone:'678',shipping:'location3'],  
3=>[name:'data2',phone:'222',shipping:'location4'],  
4=>[name:'data2',phone:'111',shipping:'location5'],  
5=>[name:'data3',phone:'555',shipping:'location6']}

The output for following below code genreates output in as:中将 output 分类为:

{data1=[],data2=[],data3=[]}

CODE:

ArrayList<String> shards = new ArrayList<String>(); // contains unique values like data1,data2,..
ArrayList<ArrayList<String>> materialData = new ArrayList<ArrayList<String>>();
HashMap<String, ArrayList<ArrayList<String>>> multiMap = new HashMap<String, ArrayList<ArrayList<String>>>();


for(String sh : shards) {
    ArrayList<ArrayList<String>> materialDataPush = new ArrayList<ArrayList<String>>();
    for (int i = 0; i < materialData.size(); i++) {
        if(sh == (materialData.get(i).get(1)).toString()){
            materialDataPush.add(materialData.get(i));
        }
    }
    multiMap.put(sh,materialDataPush);
}

the expected output should be as follows:

(
data1=>{
    0=>[name:"data1",phone:"123",shipping:"location1"],
    1=>[name:"data1",phone:"456",shipping:"location2"],
    2=>[name:"data1",phone:"678",shipping:"location3"]
    },
data2=>{
    0=>[name:"data2",phone:"222",shipping:"location4"],
    1=>[name:"data2",phone:"111",shipping:"location5"]
},
data3=>{
    0=>[name:"data3",phone:"555",shipping:"location6"]
})

Looking at the structure of your data probably you would be having a class that would have String name, phone, shipping fields. I have created a DTO class:

@Data // Lombok
public class DTO {
    private String name;
    private String phone;
    private String shipping;

    DTO() { }

    DTO(String name, String phone, String shipping) {
        this.name = name;
        this.phone = phone;
        this.shipping = shipping;
    }

    // getter/setters ommitted because of @Data
}

Here is how I tested it:

// Dummy Data (as described in question)
List<DTO> materialData = new ArrayList<>();
materialData.add(new DTO("data1", "123", "location1"));
materialData.add(new DTO("data1", "456", "location2"));
materialData.add(new DTO("data1", "678", "location3"));
materialData.add(new DTO("data2", "222", "location4"));
materialData.add(new DTO("data2", "111", "location5"));
materialData.add(new DTO("data3", "555", "location6"));

// Grouping by `name` field in DTO class
Map<String, List<DTO>> multiMap = materialData.stream().collect(Collectors.groupingBy(DTO::getName));

// Printing the results
System.out.println(multiMap);

Output (formatted JSON):

{
  "data3": [
    {
      "name": "data3",
      "phone": "555",
      "shipping": "location6"
    }
  ],
  "data2": [
    {
      "name": "data2",
      "phone": "222",
      "shipping": "location4"
    },
    {
      "name": "data2",
      "phone": "111",
      "shipping": "location5"
    }
  ],
  "data1": [
    {
      "name": "data1",
      "phone": "123",
      "shipping": "location1"
    },
    {
      "name": "data1",
      "phone": "456",
      "shipping": "location2"
    },
    {
      "name": "data1",
      "phone": "678",
      "shipping": "location3"
    }
  ]
}

Update:

Since you're not allowed to use class . I am rewriting the same functionality using Map<String, String> . Here is a utility method which I have written that will return a Map containing these values:

private static Map<String, String> createMap(String name, String phone, String shipping) {
    Map<String, String> map = new HashMap<>(3);
    map.put("name", name);
    map.put("phone", phone);
    map.put("shipping", shipping);
    return map;
}

Here is how I tested it:

// Dummy Data
List<Map<String, String>> materialData = new ArrayList<>();
materialData.add(createMap("data1", "123", "location1"));
materialData.add(createMap("data1", "456", "location2"));
materialData.add(createMap("data1", "678", "location3"));
materialData.add(createMap("data2", "222", "location4"));
materialData.add(createMap("data2", "111", "location5"));
materialData.add(createMap("data3", "555", "location6"));

// Grouping by `name` field in DTO class
Map<String, List<Map<String, String>>> multiMap = materialData.stream().collect(Collectors.groupingBy(map -> map.get("name")));

// Printing the results
System.out.println(multiMap);

The output is the same as mentioned above.

Here is way to create your Map . Just split your string on => and breaks into list of elements . Further split to get desired key and value and put inside Map . If given key found inside Map just add element against keys and so on so forth.

  public static void main(String[] args) {

    String str = "{0=>[name:'data1',phone:'123',shipping:'location1'],  \n" + 
            "1=>[name:'data1',phone:'456',shipping:'location2'],  \n" + 
            "2=>[name:'data1',phone:'678',shipping:'location3'],  \n" + 
            "3=>[name:'data2',phone:'222',shipping:'location4'],  \n" + 
            "4=>[name:'data2',phone:'111',shipping:'location5'],  \n" + 
            "5=>[name:'data3',phone:'555',shipping:'location6']}";
    HashMap<String,List<String>> result = new HashMap<String,List<String>>();
    for (String string : str.split("=>")) {
         String s = string;
         Pattern p = Pattern.compile("\\[.*?\\]");
         Matcher m = p.matcher(s);
         if(m.find()) {
             String element = (String) m.group().subSequence(1, m.group().length()-1);
            String key = element.split(":")[1].split(",")[0].replaceAll("'", "");// I am assuming you are not using any serialization API
             if(result.get(key) == null) {
                 List<String> val=new ArrayList<String>();
                 val.add(element);
                 result.put(key, val);
             }else {
                List<String> values= result.get(key); 
                values.add(element);
             }
         }
    }

    result.forEach((k,v)->{
        System.out.println(k+"  => "+v );
    });
}

Here is sample output

  data3  => [name:'data3',phone:'555',shipping:'location6']
  data2  => [name:'data2',phone:'222',shipping:'location4',  name:'data2',phone:'111',shipping:'location5']
  data1  => [name:'data1',phone:'123',shipping:'location1', name:'data1',phone:'456',shipping:'location2', name:'data1',phone:'678',shipping:'location3']

Here is the URL of sample application

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM