Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 实现N个常量之间链接的最佳方法_Java_Hashmap_Constants - Fatal编程技术网

Java 实现N个常量之间链接的最佳方法

Java 实现N个常量之间链接的最佳方法,java,hashmap,constants,Java,Hashmap,Constants,我找不到更好的标题(如果找到更好的,请随意编辑),但用例如下。我有两个常量列表。其中一个包含我在应用程序中使用的常量,另一个包含通过CSV文件发送给我的不同常量(以及数据) 举一个粗略的例子:在CSV文件中,有一个名为“客户id”的字段。在我的应用程序中,我想使用一个名为“clientId”的字段。所以我基本上需要在这两个常量之间创建一个静态链接,这样我就可以根据需要轻松地从一个常量切换到另一个常量 我曾考虑过创建一个静态的值映射(String,String),但我认为可能有更好的解决方案 谢谢

我找不到更好的标题(如果找到更好的,请随意编辑),但用例如下。我有两个常量列表。其中一个包含我在应用程序中使用的常量,另一个包含通过CSV文件发送给我的不同常量(以及数据)

举一个粗略的例子:在CSV文件中,有一个名为“客户id”的字段。在我的应用程序中,我想使用一个名为“clientId”的字段。所以我基本上需要在这两个常量之间创建一个静态链接,这样我就可以根据需要轻松地从一个常量切换到另一个常量

我曾考虑过创建一个静态的
值映射(String,String)
,但我认为可能有更好的解决方案

谢谢


编辑:将标题改为“N”常量,而不是2,因为在这种情况下Hashmap似乎不再是一个选项。

您可以使用双括号innitializer习惯用法来保持映射初始化接近映射声明,因此它不会那么“丑陋”,例如:

静态映射someMap=newhashmap(){{
放入(“一”、“二”);
放置(“三”、“四”);
}};
请注意,如果没有
static
修饰符,每个匿名类(本例中创建了一个)都会持有对封闭对象的引用,如果您将此映射的引用提供给其他某个类,则会防止封闭类被垃圾回收


幸运的是,java update为我们带来了希望,在java 9中,将有非常方便的
Map.of()
来帮助我们更安全地完成此操作。

将映射与应用程序代码分离的最佳方法是使用一个属性文件,在其中定义映射

例如,您可以在资源的根目录中有一个
csv mapping.properties
,并使用以下代码加载它们:

final Properties properties = new Properties();

properties.load( this.getClass().getResourceAsStream( "/csv-mapping.properties" ) );

这就像一个映射,增加了代码与配置的分离。

有许多方法可以用来轻松解决这些类型的问题。 一种方法是使用属性文件或包含键值对的文件

下面是属性的代码

import java.util.ResourceBundle;

public class ReadingPropertiesFile {
    public static void main(String[] args) {
         ResourceBundle messages;
         messages = ResourceBundle.getBundle("msg");
         System.out.println(messages.getString("ID"));
    }
} 
msg.properties文件包含以下值:

ID=ClientID。 产品标识=产品标识

程序的输出是ClientID


也可以从简单的文本文件中读取。或者你可以在使用地图时使用它。但是我建议您使用属性文件。

一个好的选择是使用枚举创建多个常量到单个常识值之间的映射,例如:

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public enum MappingEnum {
    CLIENT_ID("clientId",    "id of the client", "clientId", "IdOfTheClient"), 
    CLIENT_NAME("clientName",    "name of the client", "clientName");

    private Set<String> aliases;
    private String commonSenseName;

    private MappingEnum(String commonSenseName, String... aliases) {
        this.commonSenseName = commonSenseName;
        this.aliases = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(aliases)));
    }

    public static MappingEnum fromAlias(String alias) {
        for (MappingEnum mappingEnum : values()) {
            if (mappingEnum.getAliases().contains(alias)) {
                return mappingEnum;
            }
        }
        throw new RuntimeException("No MappingEnum for mapping: " + alias);
    }

    public String getCommonSenseName() {
        return commonSenseName;
    }
}

那么,使用静态映射有什么错呢?主要是它需要填充一个static(){}方法,如果列表变得很长,那么这个方法实际上是非常难看的代码。但它可能是最好的解决方案,只是想在我选择它之前确定一下。此外,如果我的应用程序中需要第三层(如我需要创建并发送给第三方的文件),并且因此需要将3个常量链接在一起,则此解决方案将不起作用。映射似乎是最好的选择,但它不必是静态的。将它封装到类中。Guava的
ImmutableMap
很棒,并且有一个很好的语法来构造它:
ImmutableMap.of(“客户端id”、“客户端id”、“客户端id”…)
。然后你也可以确定它不会被意外修改。等等什么?何时添加此功能?我从来不知道这存在@清洁工看一看这里:嗯,这实际上是相当甜蜜的。我也不知道这是存在的,就拿我的科学投票来说吧。:)我开始使用这个自动取款机了,如果一段时间内没有其他/更好的想法出现,我会接受它作为答案。谢谢!这个成语确实有缺点。例如,它创建了一个额外的.class文件。您分配给它的变量不是一个实际的HashMap,而是它的一个子类。你可以用谷歌搜索这个习惯用法的其他缺点。这不一定是个坏习惯用语;只是指出一些需要注意的事情。
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public enum MappingEnum {
    CLIENT_ID("clientId",    "id of the client", "clientId", "IdOfTheClient"), 
    CLIENT_NAME("clientName",    "name of the client", "clientName");

    private Set<String> aliases;
    private String commonSenseName;

    private MappingEnum(String commonSenseName, String... aliases) {
        this.commonSenseName = commonSenseName;
        this.aliases = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(aliases)));
    }

    public static MappingEnum fromAlias(String alias) {
        for (MappingEnum mappingEnum : values()) {
            if (mappingEnum.getAliases().contains(alias)) {
                return mappingEnum;
            }
        }
        throw new RuntimeException("No MappingEnum for mapping: " + alias);
    }

    public String getCommonSenseName() {
        return commonSenseName;
    }
}
String columnName = "id of the client";
String targetFieldName = MappingEnum.fromAlias(columnName).getCommonSenseName();