如何通过计算每个字符的出现次数将String转换为ArrayList?

时间:2017-03-20 06:43:20

标签: java json

我有一个输入字符串:

String str="1,1,2,2,2,1,3";

我想计算每个id的出现并将它们存储到List中,我想要输出像这样:

 [
  {
   "count": "3",
    "ids": "1, 2"
   }
   {
     "count": "1",
      "ids": "3"
    }
      ]

我试过像这样使用org.springframework.util.StringUtils.countOccurrencesOf(input, "a");。但在计算得不到我想要的东西之后。

8 个答案:

答案 0 :(得分:2)

这将为您提供所需的结果。首先计算每个字符的出现次数,然后按新计算HashMap<Integer, List<String>>中的每个字符进行分组。

这是一个有效的例子:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Test {

public static void main(String[] args) {

    String str = "1,1,2,2,2,1,3";

    String[] list = str.split(",");
    HashMap<String, Integer> occr = new HashMap<>();
    for (int i = 0; i < list.length; i++) {
        if (occr.containsKey(list[i])) {
            occr.put(list[i], occr.get(list[i]) + 1);
        } else {
            occr.put(list[i], 1);
        }
    }
    HashMap<Integer, List<String>> res = new HashMap<>();
    for (String key : occr.keySet()) {
        int count = occr.get(key);
        if (res.containsKey(count)) {
            res.get(count).add(key);
        } else {
            List<String> l = new ArrayList<>();
            l.add(key);
            res.put(count, l);
        }
    }

    StringBuffer sb = new StringBuffer();
    sb.append("[\n");
    for (Integer count : res.keySet()) {
        sb.append("{\n");
        List<String> finalList = res.get(count);
        sb.append("\"count\":\"" + count + "\",\n");
        sb.append("\"ids\":\"" + finalList.get(0));
        for (int i = 1; i < finalList.size(); i++) {
            sb.append("," + finalList.get(i));
        }
        sb.append("\"\n}\n");

    }
    sb.append("\n]");
    System.out.println(sb.toString());
}
}

编辑:更通用的解决方案

这是返回HashMap<Integer,List<String>>的方法,其中包含作为HashMap的键的字符串出现次数,其中每个键都包含List<String>值,其中包含所有字符串发生密钥的次数。

public HashMap<Integer, List<String>> countOccurrences(String str, String delimiter) {
    // First, we count the number of occurrences of each string.
    String[] list = str.split(delimiter);
    HashMap<String, Integer> occr = new HashMap<>();
    for (int i = 0; i < list.length; i++) {
        if (occr.containsKey(list[i])) {
            occr.put(list[i], occr.get(list[i]) + 1);
        } else {
            occr.put(list[i], 1);
        }
    }
    /** Now, we group them by the number of occurrences,
     * All strings with the same number of occurrences are put into a list;
     * this list is put into a HashMap as a value, with the number of 
     * occurrences as a key.
     */
    HashMap<Integer, List<String>> res = new HashMap<>();
    for (String key : occr.keySet()) {
        int count = occr.get(key);
        if (res.containsKey(count)) {
            res.get(count).add(key);
        } else {
            List<String> l = new ArrayList<>();
            l.add(key);
            res.put(count, l);
        }
    }
    return res;
}

答案 1 :(得分:1)

你需要做一些无聊的转移,我不确定你是否要保持ids排序。一个简单的实现是:

    public List<Map<String, Object>> countFrequency(String s) {
    // Count by char
    Map<String, Integer> countMap = new HashMap<String, Integer>();
    for (String ch : s.split(",")) {
        Integer count = countMap.get(ch);
        if (count == null) {
            count = 0;
        }
        count++;
        countMap.put(ch, count);
    }

    // Count by frequency
    Map<Integer, String> countByFrequency = new HashMap<Integer, String>();
    for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
        String chars = countByFrequency.get(entry.getValue());

        System.out.println(entry.getValue() + " " + chars);

        if (chars == null) {
            chars = "" + entry.getKey();
        } else {
            chars += ", " + entry.getKey();
        }
        countByFrequency.put(entry.getValue(), chars);
    }

    // Convert to list
    List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
    for (Map.Entry<Integer, String> entry : countByFrequency.entrySet()) {
        Map<String, Object> item = new HashMap<String, Object>();
        item.put("count", entry.getKey());
        item.put("ids", entry.getValue());
        result.add(item);
    }
    return result;
}

答案 2 :(得分:1)

嘿检查下面的代码,它可以帮助您实现预期的结果

public class Test
{
   public static void main(String args[])
   {
     String str = "1,1,2,2,2,1,3"; //Your input string

     List<String> listOfIds = Arrays.asList(str.split(",")); //Splits the string
     System.out.println("List of IDs : " + listOfIds);

     HashMap<String, List<String>> map = new HashMap<>();
     Set<String> uniqueIds = new HashSet<>(Arrays.asList(str.split(",")));
     for (String uniqueId : uniqueIds)
     {
        String frequency = String.valueOf(Collections.frequency(listOfIds, uniqueId));
        System.out.println("ID = " + uniqueId + ", frequency = " + frequency);

        if (!map.containsKey(frequency))
        {
            map.put(frequency, new ArrayList<String>());
        }
        map.get(frequency).add(uniqueId);
     }

     for (Map.Entry<String, List<String>> entry : map.entrySet())
     {
        System.out.println("Count = "+ entry.getKey() + ", IDs = " + entry.getValue());
     }
   }
}

答案 3 :(得分:0)

我建议你的方法之一是 将hashMap中的每个“字符”作为键并将“count”作为值。 这样做的示例代码是

InputVSAT_input1 = 1; 

ngOnInit() // or whatever you use to initialize your component
  this.Input = initializeFromSomewhere();
}

答案 4 :(得分:0)

<!--first you split string based on "," and store into array, after that iterate array end of array lenght in side loop  create new map and put element in map as a Key and set value as count 1 again check the key and increase count value in map-->
like....



  String str="1,1,2,2,2,1,3";
    String strArray=str.split(",");
    Map strMap=  new hashMap();
    for(int i=0; i < strArray.length(); i++){
    if(!strMap.containsKey(strArray[i])){
    strMap.put(strArray[i],1)
    }else{
    strMap.put(strArray[i],strMap.get(strArray[i])+1)
    }
    }

答案 5 :(得分:0)

String str="1,1,2,2,2,1,3";
    //Converting given string to string array
    String[] strArray = str.split(",");
    //Creating a HashMap containing char as a key and occurrences as  a value
    Map<String,Integer> charCountMap = new HashMap<String, Integer>();
     //checking each element of strArray
    for(String num :strArray){
        if(charCountMap.containsKey(num))
        {
            //If char is present in charCountMap, incrementing it's count by 1
            charCountMap.put(num, charCountMap.get(num)+1);
        }
        else
        {
            //If char is not present in charCountMap, and putting this char to charCountMap with 1 as it's value
            charCountMap.put(num, 1);
        }
    }
     //Printing the charCountMap
    for (Map.Entry<String, Integer> entry : charCountMap.entrySet())
    {
        System.out.println("ID ="+entry.getKey() + "   count=" + entry.getValue());
    }
}

答案 6 :(得分:0)

    // Split according to comma
    HashMap<String, Integer> hm = new HashMap<String, Integer>();
    for (String key : tokens) {
        if (hm.containsKey(key)) {
            Integer currentCount = hm.get(key);
            hm.put(key, ++currentCount);
        } else {
            hm.put(key, 1);
        }
    }

    // Organize info according to ID
    HashMap<Integer, String> result = new HashMap<Integer, String>();
    for (Map.Entry<String, Integer> entry : hm.entrySet()) {

        Integer newKey = entry.getValue();
        if (result.containsKey(newKey)) {
            String newValue = entry.getKey() + ", " + result.get(newKey);
            result.put(newKey, newValue);
        } else {
            result.put(newKey, entry.getKey());
        }
    }

答案 7 :(得分:0)

这是一个完整的 Java 8流媒体解决方案来解决这个问题。主要思想是首先构建每个id的出现地图,结果如下:

{1=3, 2=3, 3=1}

(首先是ID,第二是计数),然后按计数分组:

public static void main(String[] args) {
    String str = "1,1,2,2,2,1,3";

    System.out.println(
         Pattern.compile(",").splitAsStream(str)
                 .collect(groupingBy(identity(), counting()))
                 .entrySet().stream()
                 .collect(groupingBy(i -> i.getValue(), mapping( i -> i.getKey(), toList())))
    );
}

导致:

{1=[3], 3=[1, 2]}

这是我能想到的最紧凑的版本。还有更小的东西吗?

编辑:顺便说一下这里是完整的类,以便正确地导入所有静态方法:

import static java.util.function.Function.identity;
import java.util.regex.Pattern;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;

public class Java8StreamsTest6 {

    public static void main(String[] args) {
        String str = "1,1,2,2,2,1,3";

        System.out.println(
                Pattern.compile(",").splitAsStream(str)
                        .collect(groupingBy(identity(), counting()))
                        .entrySet().stream()
                        .collect(groupingBy(i -> i.getValue(), mapping(i -> i.getKey(), toList())))
        );

    }
}