- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在考虑创建一个 Hashmap 类,它允许我存储键和值。但是,只有当该值与特定类型匹配时才能存储该值,并且该类型取决于键的运行时值。例如,如果键为 EMAIL(String.class)
,则存储的值应为 String
类型。
我有以下自定义枚举:
public enum TestEnum {
TDD,
BDD,
SHIFT_RIGHT,
SHIFT_LEFT;
}
我创建了以下类(class):
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
public class test {
private static final Map<ValidKeys, Object> sessionData = new HashMap<>();
public enum ValidKeys {
EMAIL(String.class),
PASSWORD(String.class),
FIRST_NAME(String.class),
LAST_NAME(String.class),
CONDITION(TestEnum.class);
private Class type;
private boolean isList;
private Pattern pattern;
ValidKeys(Class<?> type, boolean isList) {
this.type = type;
this.isList = isList;
}
ValidKeys(Class<?> type) {
this.type = type;
}
}
public <T> void setData(ValidKeys key, T value) {
sessionData.put(key,value);
}
public Object getData(ValidKeys key) {
return key.type.cast(sessionData.get(key));
}
public static void main(String[] args) {
test t = new test();
t.setData(ValidKeys.CONDITION,TestEnum.TDD);
System.out.println(t.getData(ValidKeys.CONDITION));
}
}
我想使用 setData
和 getData
等方法并将值存储到 sessionData
中。另外,我想确保该值是否是对象列表,然后也可以正确存储。
我也在努力避免 toString 基本上我需要一个通用的 getData ,它可以在没有类型转换的情况下工作。
最佳答案
我见过一种用于此类事情的特殊模式,它是 Bloch 的类型安全异构容器模式的变体。我不知道它是否有自己的名称,但由于缺乏更好的名称,我将其称为 Typesafe Enumerated Lookup Keys。
基本上,我在各种上下文中看到的一个问题是您需要一组动态的键/值对,其中键的特定子集是具有预定义语义的“众所周知”。此外,每个键都与特定类型相关联。
“显而易见”的解决方案是使用枚举。例如,您可以这样做:
public enum LookupKey { FOO, BAR }
public final class Repository {
private final Map<LookupKey, Object> data = new HashMap<>();
public void put(LookupKey key, Object value) {
data.put(key, value);
}
public Object get(LookupKey key) {
return data.get(key);
}
}
这工作得很好,但明显的缺点是现在你需要到处转换。例如,假设您知道 LookupKey.FOO
总是有一个String
值,和LookupKey.BAR
总是有一个Integer
值(value)。你如何执行这一点?通过此实现,您不能。
此外:通过此实现,键集由枚举固定。您无法在运行时添加新的。对于某些应用程序来说这是一个优势,但在其他情况下,您确实希望在某些情况下允许使用新 key 。
这两个问题的解决方案基本上是相同的:make LookupKey
一个一流的实体,而不仅仅是一个枚举。例如:
/**
* A key that knows its own name and type.
*/
public final class LookupKey<T> {
// These are the "enumerated" keys:
public static final LookupKey<String> FOO = new LookupKey<>("FOO", String.class);
public static final LookupKey<Integer> BAR = new LookupKey<>("BAR", Integer.class);
private final String name;
private final Class<T> type;
public LookupKey(String name, Class<T> type) {
this.name = name;
this.type = type;
}
/**
* Returns the name of this key.
*/
public String name() {
return name;
}
@Override
public String toString() {
return name;
}
/**
* Cast an arbitrary object to the type of this key.
*
* @param object an arbitrary object, retrieved from a Map for example.
* @throws ClassCastException if the argument is the wrong type.
*/
public T cast(Object object) {
return type.cast(object);
}
// not shown: equals() and hashCode() implementations
}
这已经让我们完成了大部分工作。您可以引用LookupKey.FOO
和LookupKey.BAR
它们的行为就像您所期望的那样,但它们也知道相应的查找类型。您还可以通过创建 LookupKey
的新实例来定义自己的 key 。 .
如果我们想实现一些不错的类似枚举的功能,例如 static values()
方法,我们只需要添加一个注册表即可。作为奖励,我们甚至不需要 equals()
和hashCode()
如果我们添加一个注册表,因为我们现在可以通过身份比较查找键。
以下是该类最终的样子:
/**
* A key that knows its own name and type.
*/
public final class LookupKey<T> {
// This is the registry of all known keys.
// (It needs to be declared first because the create() function needs it.)
private static final Map<String, LookupKey<?>> knownKeys = new HashMap<>();
// These are the "enumerated" keys:
public static final LookupKey<String> FOO = create("FOO", String.class);
public static final LookupKey<Integer> BAR = create("BAR", Integer.class);
/**
* Create and register a new key. If a key with the same name and type
* already exists, it is returned instead (Flywheel Pattern).
*
* @param name A name to uniquely identify this key.
* @param type The type of data associated with this key.
* @throws IllegalStateException if a key with the same name but a different
* type was already registered.
*/
public static <T> LookupKey<T> create(String name, Class<T> type) {
synchronized (knownKeys) {
LookupKey<?> existing = knownKeys.get(name);
if (existing != null) {
if (existing.type != type) {
throw new IllegalStateException(
"Incompatible definition of " + name);
}
@SuppressWarnings("unchecked") // our invariant ensures this is safe
LookupKey<T> uncheckedCast = (LookupKey<T>) existing;
return uncheckedCast;
}
LookupKey<T> key = new LookupKey<>(name, type);
knownKeys.put(name, key);
return key;
}
}
/**
* Returns a list of all the currently known lookup keys.
*/
public static List<LookupKey<?>> values() {
synchronized (knownKeys) {
return Collections.unmodifiableList(
new ArrayList<>(knownKeys.values()));
}
}
private final String name;
private final Class<T> type;
// Private constructor. Only the create method should call this.
private LookupKey(String name, Class<T> type) {
this.name = name;
this.type = type;
}
/**
* Returns the name of this key.
*/
public String name() {
return name;
}
@Override
public String toString() {
return name;
}
/**
* Cast an arbitrary object to the type of this key.
*
* @param object an arbitrary object, retrieved from a Map for example.
* @throws ClassCastException if the argument is the wrong type.
*/
public T cast(Object object) {
return type.cast(object);
}
}
现在LookupKey.values()
或多或少像枚举一样工作。您还可以添加自己的 key ,以及 values()
之后将返回它们:
LookupKey<Double> myKey = LookupKey.create("CUSTOM_DATA", Double.class);
一旦你有了这个LookupKey
类,您现在可以实现一个使用这些键进行查找的类型安全存储库:
/**
* A repository of data that can be looked up using a {@link LookupKey}.
*/
public final class Repository {
private final Map<LookupKey<?>, Object> data = new HashMap<>();
/**
* Set a value in the repository.
*
* @param <T> The type of data that is being stored.
* @param key The key that identifies the value.
* @param value The corresponding value.
*/
public <T> void put(LookupKey<T> key, T value) {
data.put(key, value);
}
/**
* Gets a value from this repository.
*
* @param <T> The type of the value identified by the key.
* @param key The key that identifies the desired value.
*/
public <T> T get(LookupKey<T> key) {
return key.cast(data.get(key));
}
}
关于Java Hashmap 仅在键中存储特定类型的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53860603/
我正在运行一个辅助角色,并检查 Azure 上托管的存储中是否存在数据。当我将连接字符串用于经典类型的存储时,我的代码可以正常工作,但是当我连接到 V2 Azure 存储时,它会抛出此异常。 “远程服
在我的应用程序的主页上,我正在进行 AJAX 调用以获取应用程序各个部分所需的大量数据。该调用如下所示: var url = "/Taxonomy/GetTaxonomyList/" $.getJSO
大家好,我正在尝试将我的商店导入我的 Vuex Route-Gard。 路由器/auth-guard.js import {store} from '../store' export default
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数
我想将 Mlflow 设置为具有以下组件: 后端存储(本地):在本地使用 SQLite 数据库存储 Mlflow 实体(run_id、params、metrics...) 工件存储(远程):使用 Az
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数
我想将 Mlflow 设置为具有以下组件: 后端存储(本地):在本地使用 SQLite 数据库存储 Mlflow 实体(run_id、params、metrics...) 工件存储(远程):使用 Az
我的 Windows 计算机上的本地文件夹中有一些图像。我想将所有图像上传到同一容器中的同一 blob。 我知道如何使用 Azure Storage SDKs 上传单个文件BlockBlobServi
我尝试发出 GET 请求来获取我的 Azure Blob 存储帐户的帐户详细信息,但每次都显示身份验证失败。谁能判断形成的 header 或签名字符串是否正确或是否存在其他问题? 代码如下: cons
这是用于编写 JSON 的 NeutralinoJS 存储 API。是否可以更新 JSON 文件(推送数据),而不仅仅是用新的 JS 对象覆盖数据。怎么做到的??? // Javascript
我有一个并行阶段设置,想知道是否可以在嵌套阶段之前运行脚本,所以像这样: stage('E2E-PR-CYPRESS') { when { allOf {
我想从命令行而不是从GUI列出VirtualBox VM的详细信息。我对存储细节特别感兴趣。 当我在GUI中单击VM时,可以看到包括存储部分在内的详细信息: 但是到目前为止,我还没有找到通过命令行执行
我有大约 3500 个防洪设施,我想将它们表示为一个网络来确定流动路径(本质上是一个有向图)。我目前正在使用 SqlServer 和 CTE 来递归检查所有节点及其上游组件,只要上游路径没有 fork
谁能告诉我 jquery data() 在哪里存储数据以及何时删除以及如何删除? 如果我用它来存储ajax调用结果,会有性能问题吗? 例如: $("body").data("test", { myDa
有人可以建议如何为 Firebase 存储中的文件设置备份。我能够备份数据库,但不确定如何为 firebase 存储中的文件(我有图像)设置定期备份。 最佳答案 如何进行 Firebase 存储的本地
我最近开始使用 firebase 存储和 firebase 功能。现在我一直在开发从功能到存储的文件上传。 我已经让它工作了(上传完成并且文件出现在存储部分),但是,图像永远保持这样(永远在右侧加载)
我想只允许用户将文件上传到他们自己的存储桶中,最大文件大小为 1MB,仍然允许他们删除文件。我添加了以下内容: match /myusers/{userId}/{allPaths=**} { al
使用生命周期管理策略将容器的内容从冷访问层移动到存档。我正在尝试以下策略,希望它能在一天后将该容器中的所有文件移动到存档层,但事实并非如此在职的。我设置了选择标准“一天未使用后”。 这是 json 代
对于连接到 Azure 存储端点,有 http 和 https 两个选项。 第一。 https 会带来开销,可能是 5%-10%,但我不支付同一个数据中心的费用。 第二。 http 更快,但 Auth
有人可以帮我理解这一点吗?我创建了Virtual Machine in Azure running Windows Server 2012 。我注意到 Azure 自动创建了一个存储帐户。当我进入该存
我是一名优秀的程序员,十分优秀!