首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我想从下面的hashmap获得公共时间集的工作日

我想从下面的hashmap获得公共时间集的工作日
EN

Code Review用户
提问于 2018-02-06 09:18:35
回答 3查看 335关注 0票数 0

我有以下HashMap

代码语言:javascript
运行
复制
  HashMap<String, String> days = new HashMap<String, String>(){
        days.put("MON", "9-5");
        days.put("TUE", "9-4");
        days.put("WED", "9-5");
        days.put("THU", "9-5");
        days.put("FR", "9-5");
        days.put("SAT", "Closed");
        days.put("SUN", "Closed");
};

我想显示以下输出:

TUE: 9-4, SAT-SUN :闭幕式

注意: hashmap("9-5")的值可能会根据来自管理面板的输入而改变。

我已经完成了以下代码,但是它太长了:

代码语言:javascript
运行
复制
    private void days() {

         String timing1 = null;
         String timing2 = null;
         String timing3 = null;
         String timing4 = null;
         String timing5 = null;
         String timing6 = null;
         String timing7 = null;

         ArrayList<String> time1 =new ArrayList<>();
         ArrayList<String> time2 =new ArrayList<>();
         ArrayList<String> time3 =new ArrayList<>();
         ArrayList<String> time4 =new ArrayList<>();
         ArrayList<String> time5 =new ArrayList<>();
         ArrayList<String> time6 =new ArrayList<>();
         ArrayList<String> time7 =new ArrayList<>();

         //iterating over the hash map and taking value ie time storing in respected variable

        for (Map.Entry<String, String> entry : days.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            System.out.println("key" + key + "Val" + value.toString());


            if (timing1 ==null || timing1.equals(value.toString())){
                timing1 = value.toString();
                continue;
            }

            if (timing2 ==null || timing2.equals(value.toString())){
                timing2 = value.toString();
                continue;
            }

            if (timing3 ==null || timing3.equals(value.toString())){
                timing3 = value.toString();
                continue;
            }

            if (timing4 ==null || timing4.equals(value.toString())){
                timing4 = value.toString();
                continue;
            }

            if (timing5 ==null || timing5.equals(value.toString())){
                timing5 = value.toString();
                continue;
            }

            if (timing6 ==null || timing6.equals(value.toString())){
                timing6 = value.toString();
                continue;
            }

            if (timing7 ==null || timing7.equals(value.toString())){
                timing7 = value.toString();

            }


        }


         //based on value from hash-map appending the key ie. days name(eg. MON) to the respected array-list

        for (Map.Entry<String, String> entry : days.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();


            if (timing1!=null && timing1.equals(value.toString())){

                time1.add(key);
                continue;
            }

            if (timing2!=null && timing2.equals(value.toString())){

                time2.add(key);
                continue;
            }

            if (timing3!=null && timing3.equals(value.toString())){

                time3.add(key);
                continue;
            }

            if (timing4!=null && timing4.equals(value.toString())){

                time4.add(key);
                continue;
            }

            if (timing5!=null && timing5.equals(value.toString())){

                time5.add(key);
                continue;
            }

            if (timing6!=null && timing6.equals(value.toString())){

                time6.add(key);
                continue;
            }

            if (timing7!=null && timing7.equals(value.toString())){

                time7.add(key);
               // continue;
            }

        }
EN

回答 3

Code Review用户

发布于 2018-02-06 12:59:19

您需要做的事情通常称为“分组”,即迭代给定的数据集,获取一个属性(在您的示例中是时间),并在一个有用的结构中收集具有相同属性的条目。

幸运的是,java (8+)已经可以通过遍历映射条目并自动对它们进行分组来为您做到这一点:

代码语言:javascript
运行
复制
    Map<String, List<Map.Entry<String, String>>> grouped = days.entrySet().stream()
        .collect(Collectors.groupingBy(Map.Entry::getValue));

好的,这里的数据结构看起来有点复杂,因为您的列表包含了地图条目,但这是主要工作。如果打印此结果,您已经得到(手动添加的格式):

代码语言:javascript
运行
复制
{
     9-4=[TUE=9-4],
     9-5=[MON=9-5, WED=9-5, THU=9-5, FRI=9-5],
     Closed=[SAT=Closed, SUN=Closed]
}

..。从数据的角度来看,这正是您所需要的。使用对此映射的进一步迭代(使用时间作为键,而旧映射的条目作为值来格式化相应的输出)应该是非常简单的。

顺便说一句:为了保持日常生活的秩序,你应该使用LinkedHashMap而不是HashMap。

票数 1
EN

Code Review用户

发布于 2018-02-06 11:15:40

你应该做的是倒转地图,键变成值,反之亦然,但是我想出了这样的东西:

代码语言:javascript
运行
复制
  public static void daysOfWeek() {
     Map<String, List<String>> ret = new HashMap<>();
    Map<String, String> days = new HashMap<>();
    days.put("MON", "9-5");
    days.put("TUE", "9-4");
    days.put("WED", "9-5");
    days.put("THU", "9-5");
    days.put("FR", "9-5");
    days.put("SAT", "Closed");
    days.put("SUN", "Closed");

    for (Map.Entry<String, String> next : days.entrySet()) {
        String key = next.getKey();
        String value = next.getValue();
        List<String> list;
        if (ret.containsKey(value)) {
            list = ret.get(value);
        } else {
            list = new ArrayList<>();
            ret.put(value, list);
        }
        list.add(key);

    }

    System.out.println(StringifyMap(ret));
}

private static String StringifyMap(Map<String, List<String>> map) {
    StringBuilder sb = new StringBuilder();

    for (Map.Entry<String, List<String>> next : map.entrySet()) {
        List<String> days = next.getValue();
        String hour = next.getKey();
        for (int i = 0; i < days.size(); i++) {

            sb.append(days.get(i));
            if (i < days.size() - 1)
                sb.append('-');
        }
        sb.append(':').append(hour);
        sb.append('\n');

    }

    return sb.toString();
}
票数 0
EN

Code Review用户

发布于 2018-02-06 11:22:45

类型作为接口

HashMap days =新HashMap(){

可能只是

代码语言:javascript
运行
复制
  Map<String, String> days = new HashMap<>() {

作为一般规则,您可以将代码编码到接口,而不是实现。

我还删除了不必要的第二个声明,以便留给编译器来使其正确。这不仅缩短了,而且它使修改地图类型变得更容易,因为您只需要在一个地方这样做。

避免编号变量

这里的一个问题是,您必须手动写出每个关系。相反,设置您的数据结构来处理这个问题。

代码语言:javascript
运行
复制
    private void days() {
        System.out.println(buildScheduleString());
    }

    private String buildScheduleString() {
        List<String> orderedDays
            = new ArrayList<>(Arrays.asList(
                "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"));

        Map<String, String> openHours = invertMap(days);

        List<String> lines = new ArrayList<>();
        for (String day: orderedDays) {
            String schedule = days.get(day);

            List<String> scheduledDays = openHours.get(schedule);
            if (scheduledDays != null) {
                StringBuilder builder = new StringBuilder();

                // unimplemented building of string

                lines.add(builder.toString());

                openHours.remove(schedule);
            }
        }

        // unimplemented return
    }

    public Map<String, String> invertMap(Map<String, String> map) {
        Map<String, String> result = new HashMap<>();

        for (Map.Entry<String, String> entry : map.entrySet()) {
            List<String> list = result.get(entry.getValue());
            if (list == null) {
                list = new ArrayList<String>();
                result.put(entry.getValue(), list);
            }

            list.add(entry.getKey());
        }

        return result;
    }

我在这里留下了您在原始代码中没有实现的部分。提示:如果您使用的是Java 8,您可以在这两个地方使用String.join

这将打印与字符串的构建分离开来,以便在将来的其他上下文中重用buildScheduleString

这将创建一个实用程序方法(invertMap),它可以在将来的其他上下文中使用。它可能有一个更好的名称,因为它只用于使用Map<String, String>

您可以在其他地方定义orderedDaysopenHours。我在这里定义了它们,因为这是你的背景。

通过在使用schedule之后删除它,我们可以使它不再重复显示相同的行。

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

https://codereview.stackexchange.com/questions/186899

复制
相关文章

相似问题

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