首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用HashMap解析字符串以进行格式化

使用HashMap解析字符串以进行格式化
EN

Stack Overflow用户
提问于 2020-02-27 05:05:42
回答 4查看 73关注 0票数 0

我正在编写Java字符串格式化程序,我认为我正在使它变得比它更复杂?我有一个文件给出了一个商店列表:

代码语言:javascript
复制
"100|Pete's Pizza Palace|George Smith|200"
"400|Pete's Pizza Palace|George Smith|30"
"320|Pete's Pizza Palace|George Smith|-13"
"310|Pete's Pizza Palace|John Smith|2"

输出应该看上去:“皮特的比萨宫--乔治·史密斯-217,皮特的披萨--帕拉卡--约翰·史密斯--2”

因此,在第一节中删除了存储号,然后是相同商店的附加利润。我似乎并不是为了得到同一键串的和而在地图上放进去的。

代码语言:javascript
复制
static String fileRecords(String[] records) {
    int len = records.length;
    Map<String, Integer> map = new HashMap<String, Integer>();
    Map<String, Integer> profitTotals = new HashMap<String, Integer>();
    String[] record = new String[len];
    int index = 0;
    int[] sums = new int[len];
    StringBuilder sb = new StringBuilder();
    StringBuilder tempStringBuilder = new StringBuilder();
    int totalSum = 0;
    for(int i = 0;i<len;i++) {
        record = records[i].split("\\|");
        String recEntryNameString = tempStringBuilder.append(record[1]).append("|").append(record[2]).append("|").toString();
        map.put(recEntryNameString, Integer.parseInt(record[3]));   
        profitTotals.put(recEntryNameString, Integer.parseInt(record[3])); 
        Iterator iter = map.entrySet().iterator();
        for (Map.Entry<String, Integer> entries : map.entrySet()) {
            for(Map.Entry<String, Integer> sumNum : profitTotals.entrySet()) {
                if(!entries.getKey().equals(sumNum.getKey())) {
                    totalSum = entries.getKey() + sumNum.getKey();
                    map.replace(recEntryNameString, entries.getKey(), totalSum);    
                    profitTotals.remove(recEntryNameString);
                }
            }
        }
    }
    Iterator<String, Integer> iter = map.entrySet().iterator();
    while(iter.hasNext()) {
        Map.Entry<String, Integer> entry = iter.next();
        if(iter.hasNext()==true)
            sb.append(entry.getKey()).append(entry.getValue()).append(",");
        else
            sb.append(entry.getKey()).append(entry.getValue());
    }
    return sb.toString();
}

我得到的输出非常接近,但是再次寻找正确的格式。

代码语言:javascript
复制
Pete's Pizza Palace|George Smith|Pete's Pizza Palace|George Smith|Pete's Pizza Palace|George 
Smith|87,Pete's Pizza Palace|George Smith|100,Pete's Pizza Palace|George Smith|Pete's Pizza 
 Palace|George Smith|123,
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-02-27 05:59:55

我非常喜欢Kartik关于在Java语言中使用新特性的答案。

稍微容易理解的可能是:

代码语言:javascript
复制
public class PizzaStore {

static String[] records = new String[]{"100|Pete's Pizza Palace|George Smith|200",
    "400|Pete's Pizza Palace|George Smith|30",
    "320|Pete's Pizza Palace|George Smith|-13",
    "310|Pete's Pizza Palace|John Smith|2"};

public static void main(String[] args) {
    fileRecords(records);
}

static void fileRecords(String[] records) {

    int len = records.length;

    HashMap<String, Integer> runningTotals = new HashMap<>();

    for (int i = 0; i < len; i++) {
        String rec = records[i];
        String[] fields = rec.split("\\|");
        String storeName = fields[1] + "|" + fields[2];
        Integer value = new Integer(fields[3]);
        if (!runningTotals.containsKey(storeName)) {
            runningTotals.put(storeName, 0);            
        }
        runningTotals.put(storeName, runningTotals.get(storeName) + value);
    }

    for (String s : runningTotals.keySet()) {
        System.out.println(s + "|" + runningTotals.get(s));
    }

}
}

在这里,我们使用的洞察力(归功于卡蒂克),即两个中间字符串可以连接成一个键。

输出如下:

皮特必胜客宫乔治史密斯217

皮特比萨宫约翰·史密斯2

例如,在不同的行上分开,但这很容易调整(将println更改为打印,并在它们之间插入“AC.26”)。

票数 0
EN

Stack Overflow用户

发布于 2020-02-27 05:42:48

首先表示类中的数据:

代码语言:javascript
复制
public class Transaction {
    private int id;
    private String place;
    private String customer;
    private double amount;

    Transaction(String tokenizedString) {
        String[] tokens = tokenizedString.split("\\|");
        id = Integer.parseInt(tokens[0]);
        place = tokens[1];
        customer = tokens[2];
        amount = Double.parseDouble(tokens[3]);
    }

    //getters/setters
}

然后你可以像这样使用它:

代码语言:javascript
复制
public static void main(String[] args) {
    List<String> list = List.of(
            "100|Pete's Pizza Palace|George Smith|200",
            "400|Pete's Pizza Palace|George Smith|30",
            "320|Pete's Pizza Palace|George Smith|-13",
            "310|Pete's Pizza Palace|John Smith|2"
    );
    Map<String, Double> map = list.stream()
            .map(Transaction::new)
            .collect(Collectors.groupingBy(
                    o -> String.join("|", o.getPlace(), o.getCustomer()),
                    Collectors.summingDouble(Transaction::getAmount)));
    List<String> result = map.entrySet().stream()
            .map(e -> e.getKey() + "|" + e.getValue())
            .collect(Collectors.toList());
    System.out.println(result);
}

输出

代码语言:javascript
复制
[Pete's Pizza Palace|George Smith|217.0, Pete's Pizza Palace|John Smith|2.0]

解释

.map(Transaction::new)

由于参数化构造函数,将字符串列表中的每个项转换为Transaction

然后,我根据placecustomer的组合字符串对事务进行分组,用分隔符|分隔。

这给了我一张地图,上面有像"Pete's Pizza Palace|George Smith" -> 217.0这样的条目

最后,我将每个条目映射到一个字符串,该字符串是将键和值组合在一起的结果,由|分隔,并将它们收集到一个列表中。

我尝试完成收集groupingBy下游收集器中的列表的最后一步,但没有找到一种方法。

票数 3
EN

Stack Overflow用户

发布于 2020-02-27 05:23:43

我将创建一个中间对象作为数据持有者,以包含这些记录。

代码语言:javascript
复制
class PizzaStore {

    int storeID;
    String franchiseName;
    String managerName;
    // if this is supposed to be a currency value use BigDecimal instead
    int profitability;

 }

大多数IDE可以添加setter和getter方法,如果要使它们受到保护或私有的话。

然后,需要构造函数才能将记录转换为比萨饼店。

代码语言:javascript
复制
     public PizzaStore(String record) {
         if (record == null) {
             // initialize to default values and return
             // don't want to throw exceptions in constructors
             // ...
             return;
         }

         String[] fields = record.split("\\|");

         if (fields.length < 4) {
             // initialize to default values and return
             // don't want to throw exceptions in constructors
             // ...
             return;
         }

         this.franchiseName = fields[1];
         this.managerName = fields[2];


         try {
             Integer id = new Integer(fields[0]);
             Integer profit = new Integer(fields[3]);
         } catch (Exception e) {
             System.err.println("failed to parse fields: " + fields[0] + " - " + fields[3]);    
             // initialise them to something
         }
     }

然后你需要一个数据结构来存储它们。您可以使用数组,但是如果要通过storeID (例如)将它们从数据结构中提取出来,并且storeID是唯一的,那么您可以创建一个HashMap,并将存储号作为键,将比萨饼商店作为值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60426545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档