从 HashMap 构造一个 class
Construct a class from HashMap
我想编写一个构造函数来设置 HashMap 中的值。你能告诉我最好的方法是什么吗?
写到现在我正在使用switch语句调用基于HashMap键的方法,但是我想知道是否有更好的选择。
仅供参考,在 myItems class 中,我实际上有 25 个变量要设置。
public class MainClass{
BufferedReader br = new BufferedReader(new FileReader(file));
String[] datakey = br.readLine().split(";"); // getting header, 25 of them
HashMap<String,String> bookmap = new HashMap<String,String>();
String[] dataarr = line.split(";"); // getting values, 25 of them
int k = 0;
for(String d : datakey){
bookmap.put(d, dataarr[k++]); // Key-Value Pair
}
myItems item = new myItems(bookmap); // HOW TO WRITE THIS CONSTRUCTOR?
}
public class myItems {
String _id="";
String _name="";
String _genre="";
String _language="";
int _rating=0;
int _price=0;
...........................
...//25 OF THEM...
...........................
public myItems(HashMap<String,String> allrec){
Iterator<Map.Entry<String,String>> it = allrec.entrySet().iterator();
while(it.hasNext()){
Map.Entry pairs = (Map.Entry)it.next();
Switch(pairs.getKey()){
case "id":
setid(pairs.getValue());
break;
case "name":
setname(pairs.getValue());
break;
Deafult:
break;
}
}
}
public int getid(){
return this._id;
}
public String getname(){
return this._name;
}
..............................
..............................
..............................
public void setid(int id){
this._id = id;
}
public void setname(String name){
this._name = name;
}
..............................
..............................
..............................
}
你为什么不直接这样写呢:
public myItems(HashMap<String,String> allrec){
setid(allrec.get("id");
setname(allrec.get("name");
}
如果您不想为任何属性分配空值,那么您应该检查地图 returns 是否为空值:
public myItems(HashMap<String,String> allrec){
String id = allrec.get(id);
if(id != null)
setid(id);
// ...
}
实际上您的问题还有另一种解决方案。为什么还要费心将这些值存储在属性中呢?您可以将它们存储在 Map 本身中。你的构造函数将是这样的:
private Map<String, String> mAttributes;
public myItems(HashMap<String, String> allrec) {
mAttributes = allrec;
}
请注意,您应该考虑制作整个地图的副本,而不是像上面那样存储参考。然后这样写set方法:
public void setId(String id) {
mAttributes.put("id", id);
}
你的get方法是这样的:
public String getId() {
return mAttributes.get("id");
}
您可以为此使用 Reflection。想象一下,一些字段有 setter(对于数据结构是好的,对于 类 是有问题的——可变性和不变性呢?),其他的则没有。那么你可以这样做:
import java.lang.reflect.Method;
public void setAll(final Map<String, String> fieldMap) {
for (final Map.Entry<String, String> entry : fieldMap.entrySet())
setField(entry);
}
public void setField(final Map.Entry<String, String> entry) {
setField(entry.getKey(), entry.getValue());
}
public void setField(final String name, final String value) {
final Method fieldSetter = getFieldSetter(name);
if (fieldSetter != null) {
fieldSetter.invoke(this, value);
return;
}
final Field field = getField(name);
if (field != null) {
field.set(this, value);
return;
}
// Throw some exception
}
public Method getFieldSetter(final String fieldName) {
return getMethod(getSetterName(fieldName));
}
public static String getSetterName(final String fieldName) {
return "set" + upperCaseFirst(fieldName);
}
public static String upperCaseFirst(final String s) {
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
public Method getMethod(final String methodName) {
final Class<?> clazz = getClass();
try {
return clazz.getMethod(methodName, String.class);
} catch (final NoSuchMethodException ignore) { }
try {
return clazz.getDeclaredMethod(methodName, String.class);
} catch (final NoSuchMethodException ignore) { }
return null;
}
public Field getField(final String fieldName) {
final Class<?> clazz = getClass();
try {
return clazz.getField(fieldName);
} catch (final NoSuchFieldException ignore) { }
try {
return clazz.getDeclaredField(fieldName);
} catch (final NoSuchFieldException ignore) { }
return null;
}
- 有一些异常需要处理,您需要相应地更改源代码。
- AFAIR on Android Reflection 会带来性能损失。您可能需要关注该方法的性能。
我想编写一个构造函数来设置 HashMap 中的值。你能告诉我最好的方法是什么吗?
写到现在我正在使用switch语句调用基于HashMap键的方法,但是我想知道是否有更好的选择。
仅供参考,在 myItems class 中,我实际上有 25 个变量要设置。
public class MainClass{
BufferedReader br = new BufferedReader(new FileReader(file));
String[] datakey = br.readLine().split(";"); // getting header, 25 of them
HashMap<String,String> bookmap = new HashMap<String,String>();
String[] dataarr = line.split(";"); // getting values, 25 of them
int k = 0;
for(String d : datakey){
bookmap.put(d, dataarr[k++]); // Key-Value Pair
}
myItems item = new myItems(bookmap); // HOW TO WRITE THIS CONSTRUCTOR?
}
public class myItems {
String _id="";
String _name="";
String _genre="";
String _language="";
int _rating=0;
int _price=0;
...........................
...//25 OF THEM...
...........................
public myItems(HashMap<String,String> allrec){
Iterator<Map.Entry<String,String>> it = allrec.entrySet().iterator();
while(it.hasNext()){
Map.Entry pairs = (Map.Entry)it.next();
Switch(pairs.getKey()){
case "id":
setid(pairs.getValue());
break;
case "name":
setname(pairs.getValue());
break;
Deafult:
break;
}
}
}
public int getid(){
return this._id;
}
public String getname(){
return this._name;
}
..............................
..............................
..............................
public void setid(int id){
this._id = id;
}
public void setname(String name){
this._name = name;
}
..............................
..............................
..............................
}
你为什么不直接这样写呢:
public myItems(HashMap<String,String> allrec){
setid(allrec.get("id");
setname(allrec.get("name");
}
如果您不想为任何属性分配空值,那么您应该检查地图 returns 是否为空值:
public myItems(HashMap<String,String> allrec){
String id = allrec.get(id);
if(id != null)
setid(id);
// ...
}
实际上您的问题还有另一种解决方案。为什么还要费心将这些值存储在属性中呢?您可以将它们存储在 Map 本身中。你的构造函数将是这样的:
private Map<String, String> mAttributes;
public myItems(HashMap<String, String> allrec) {
mAttributes = allrec;
}
请注意,您应该考虑制作整个地图的副本,而不是像上面那样存储参考。然后这样写set方法:
public void setId(String id) {
mAttributes.put("id", id);
}
你的get方法是这样的:
public String getId() {
return mAttributes.get("id");
}
您可以为此使用 Reflection。想象一下,一些字段有 setter(对于数据结构是好的,对于 类 是有问题的——可变性和不变性呢?),其他的则没有。那么你可以这样做:
import java.lang.reflect.Method;
public void setAll(final Map<String, String> fieldMap) {
for (final Map.Entry<String, String> entry : fieldMap.entrySet())
setField(entry);
}
public void setField(final Map.Entry<String, String> entry) {
setField(entry.getKey(), entry.getValue());
}
public void setField(final String name, final String value) {
final Method fieldSetter = getFieldSetter(name);
if (fieldSetter != null) {
fieldSetter.invoke(this, value);
return;
}
final Field field = getField(name);
if (field != null) {
field.set(this, value);
return;
}
// Throw some exception
}
public Method getFieldSetter(final String fieldName) {
return getMethod(getSetterName(fieldName));
}
public static String getSetterName(final String fieldName) {
return "set" + upperCaseFirst(fieldName);
}
public static String upperCaseFirst(final String s) {
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
public Method getMethod(final String methodName) {
final Class<?> clazz = getClass();
try {
return clazz.getMethod(methodName, String.class);
} catch (final NoSuchMethodException ignore) { }
try {
return clazz.getDeclaredMethod(methodName, String.class);
} catch (final NoSuchMethodException ignore) { }
return null;
}
public Field getField(final String fieldName) {
final Class<?> clazz = getClass();
try {
return clazz.getField(fieldName);
} catch (final NoSuchFieldException ignore) { }
try {
return clazz.getDeclaredField(fieldName);
} catch (final NoSuchFieldException ignore) { }
return null;
}
- 有一些异常需要处理,您需要相应地更改源代码。
- AFAIR on Android Reflection 会带来性能损失。您可能需要关注该方法的性能。