繁体   English   中英

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

[英]How can I convert a String into ArrayList by counting occurrence of each characters?

我有一个输入字符串为:

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"); 像这样。 但是在算不上我想要的东西之后。

这将为您提供所需的结果。 首先计算每个字符的出现次数,然后在新的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;
}

您需要进行一些无聊的传输,我不确定是否要对ID进行排序。 一个简单的实现是:

    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;
}

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

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());
     }
   }
}

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

    String str = "1,1,2,2,2,1,3";
    HashMap<String, String> map = new HashMap();
    for (String c : str.split(",")) {
        if (map.containsKey( c)) {
            int count = Integer.parseInt(map.get(c));
            map.put(c, ++count + "");
        } else
            map.put(c, "1");
    }
    System.out.println(map.toString());
}
<!--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)
    }
    }
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());
    }
}
    // 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());
        }
    }

这里是解决该问题的完整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())))
        );

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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