Java 将字符串与对象创建关联
我有一个相当基本的Java类和一些类变量。我已经过度使用toString()来提供字符串输出(最终将输出到文本文件) 我试图优雅地创建一种方法,让我使用这个字符串输出重新创建对象,并像以前一样设置所有变量。这个类看起来像这样:Java 将字符串与对象创建关联,java,object,reflection,Java,Object,Reflection,我有一个相当基本的Java类和一些类变量。我已经过度使用toString()来提供字符串输出(最终将输出到文本文件) 我试图优雅地创建一种方法,让我使用这个字符串输出重新创建对象,并像以前一样设置所有变量。这个类看起来像这样: public class Report { private String itemA; private String itemB; private String itemC; @Override public String to
public class Report {
private String itemA;
private String itemB;
private String itemC;
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Items are::");
sb.append("\nItem A is: ").append(itemA);
sb.append("\nItem B is: ").append(itemB);
sb.append("\nItem C is: ").append(itemC);
return sb.toString();
}
}
这就是我可以使用反射来解决它的潜在方法:
public class Report {
private String itemA;
private String itemB;
private String itemC;
private final Map<String, String> MAPPING = new HashMap<>();
public Report(String itemA, String itemB, String itemC) {
this.itemA = itemA;
this.itemB = itemB;
this.itemC = itemC;
MAPPING.put("Item A is: ", "itemA");
MAPPING.put("Item B is: ", "itemB");
MAPPING.put("Item C is: ", "itemC");
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Items are::");
MAPPING.entrySet().forEach(entry -> {
sb.append("\n").append(entry.getKey()).append(BeanUtils.getProperty(this, entry.getValue()));
});
return sb.toString();
}
public Report createReportFromString(String reportString) {
List<String> reportLines = Arrays.asList(reportString.split("\n"));
HashMap<String, String> stringObjectRelationship = new HashMap<>();
reportLines.forEach(reportLine -> {
Optional<String> matchingKey = MAPPING.keySet().stream().filter(reportLine::contains).findFirst();
matchingKey.ifPresent(key -> {stringObjectRelationship.put(MAPPING.get(key), reportLine.split(key)[1]);});
});
stringObjectRelationship.forEach((variableName, variableValue) -> BeanUtils.setProperty(this, variableName, variableValue));
return this;
}
}
公共类报告{
私有字符串项a;
私有字符串项b;
私有字符串项c;
私有最终映射=新HashMap();
公共报告(字符串项A、字符串项B、字符串项C){
this.itemA=itemA;
this.itemB=itemB;
this.itemC=itemC;
MAPPING.put(“项目A为:”,“项目A”);
put(“B项为:”,“B项”);
put(“C项为:”,“C项”);
}
@凌驾
公共字符串toString(){
StringBuilder sb=新的StringBuilder();
sb.追加(“项目为::”);
MAPPING.entrySet().forEach(条目->{
sb.append(“\n”).append(entry.getKey()).append(BeanUtils.getProperty(this,entry.getValue());
});
使某人返回字符串();
}
公共报表createReportFromString(String reportString){
List reportLines=Arrays.asList(reportString.split(“\n”);
HashMap stringObjectRelationship=新建HashMap();
reportLines.forEach(reportLine->{
可选matchingKey=MAPPING.keySet().stream().filter(reportLine::contains).findFirst();
matchingKey.ifPresent(key->{stringObjectRelationship.put(MAPPING.get(key)、reportLine.split(key)[1]);});
});
stringObjectRelationship.forEach((variableName,variableValue)->BeanUtils.setProperty(this,variableName,variableValue));
归还这个;
}
}
我基本上希望将报表中的键(“项A是:”)与相应变量的名称(“项A”)关联起来,并在toString()方法和createReportFromString(String String)方法中使用此关系。现在,当执行此操作时,有很多可能的异常可以抛出,需要处理或抛出-然后它看起来没有我想要的那么优雅
我不知道这是否可以在没有反射的情况下实现——或者我可以重新安排这个类使之成为可能
我不能更改的是toString()中字符串输出的结构
@JimboMcHiggins假设我可以更改toString输出,那么您如何将序列化和反序列化与一些常见的映射联系起来 我将保持toString不变,并将序列化的责任转移到java.io.Serializable。如果这不是一个可接受的方法,请纠正我。映射将由报表pojo的类字段定义。这还允许您在不中断现有对象的反序列化的情况下更改toString
import java.io.Serializable;
public class Report implements Serializable {
private static final long serialVersionUID = 1L;
private String itemA;
private String itemB;
private String itemC;
public Report(String itemA, String itemB, String itemC) {
this.itemA = itemA;
this.itemB = itemB;
this.itemC = itemC;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Items are::");
sb.append("\nItem A is: ").append(itemA);
sb.append("\nItem B is: ").append(itemB);
sb.append("\nItem C is: ").append(itemC);
return sb.toString();
}
}
示例用法
public class Test1 {
public static void main(String[] args) {
Report report = new Report("W", "O", "W");
System.out.println(report);
String filename = "file.ser";
// Serialization
try
{
//Saving of report in a file
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);
// Method for serialization of report
out.writeObject(report);
out.close();
file.close();
System.out.println("Report has been serialized");
}
catch(IOException ex)
{
System.out.println("IOException is caught");
}
Report report1 = null;
// Deserialization
try
{
// Reading the report from a file
FileInputStream file = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(file);
// Method for deserialization of report
report1 = (Report)in.readObject();
in.close();
file.close();
System.out.println("Report has been deserialized ");
System.out.println(report1);
}
catch(IOException ex)
{
System.out.println("IOException is caught");
}
catch(ClassNotFoundException ex)
{
System.out.println("ClassNotFoundException is caught");
}
}
}
输出
Items are::
Item A is: W
Item B is: O
Item C is: W
Report has been serialized
Report has been deserialized
Items are::
Item A is: W
Item B is: O
Item C is: W
反射具有多个特征:
公共类报告{
静态最终类元素{
最终字符串标题;
最终功能吸气剂;
最终双消费者设定者;
最终模式;
元素(字符串头,
函数getter、双消费者setter){
this.header=头;
this.getter=getter;
this.setter=setter;
pattern=pattern.compile(“^\\Q”+头+”\\E(.*?$”,pattern.MULTILINE);
}
}
静态最终列表元素=List.of(
新元素(“项目A为:”,报告::getItemA,报告::setItemA),
新元素(“项B为:”,报告::getItemB,报告::setItemB),
新元素(“项C为:”,报告::getItemC,报告::setItemC));
私有字符串itemA、itemB、itemC;
公共报告(字符串项A、字符串项B、字符串项C){
this.itemA=itemA;
this.itemB=itemB;
this.itemC=itemC;
}
@重写公共字符串toString(){
StringBuilder sb=新的StringBuilder();
sb.追加(“项目为:”);
元素。forEach(e->
sb.append('\n').append(e.header).append(e.getter.apply(this));
使某人返回字符串();
}
公共静态报表createReportFromString(String reportString){
返回新报表(“,”“,”).setValuesFromString(reportString);
}
公共报告集合值fromstring(String reportString){
匹配器m=null;
对于(元素e:元素){
如果(m==null)m=e.pattern.matcher(reportString);
else m.usePattern(e.pattern).reset();
如果(!m.find())
抛出新的IllegalArgumentException(“缺少\”“+e.header+”);
e、 setter.accept(这个,m.group(1));
}
归还这个;
}
公共字符串getItemA(){
返回项目a;
}
公共void setItemA(字符串itemA){
this.itemA=itemA;
}
公共字符串getItemB(){
返回项目B;
}
公共void setItemB(字符串itemB){
this.itemB=itemB;
}
公共字符串getItemC(){
返回项目c;
}