如何从LinkedHashMap的值中提取类实例的属性?
如何打印LinkedHashMap中自定义类实例的具体属性
我首次使用LinkedHashMap,集合的键为String类型,值是自定义类的实例。定义了GeoElement基类,以及继承它的PointElement、LineElement子类,集合定义如下:
public static LinkedHashMap<String, GeoElement> geoElemMap = new LinkedHashMap<String, GeoElement>(); // 用于GUI与代码间的数据传输
这个集合用来在GUI和代码之间传输数据,存储的元素要么是<点名称,点坐标>,要么是<线名称,线属性>。我写了linkedHashMapTest方法打印集合内容,但输出结果只有类名@内存地址的形式(示例:Key: ZERO, Value: MyNewGUI$PointElement@5ce1e0d4),看不到实例的具体属性。想知道怎么提取并打印geoElemMap值部分里的几何元素属性?
附自定义类代码:
// --- 几何元素基类 --------- class GeoElement { String elemType = "Generic"; // 元素类型 } // --- 点元素类 --------- class PointElement extends GeoElement { final String elemType = "Point"; String pointName = ""; // 点名称 double pointCoord[] = {0.0, 0.0, 0.0}; // 点坐标 public PointElement(String pName, double px, double py, double pz) // 重载构造方法 { this.pointName = pName; this.pointCoord[0] = px; this.pointCoord[1] = py; this.pointCoord[2] = pz; } } // --- 线元素类 --------- class LineElement extends GeoElement { final String elemType = "Line"; String lineName = ""; // 线名称 String startPoint = ""; // 起点或锚点 String endPoint = ""; // 终点(仅两点线使用) String angle = ""; // 角度(度) String oldLineName = ""; // 基线名称 String startPointMethod = ""; // 起点生成方法 String startParam = ""; // 起点参数 String endPointMethod = ""; // 终点生成方法 String endParam = ""; // 终点参数 String groupName = ""; // 组名称 // --------------------------------------------- 重载构造方法 -------------------------------------------------------------------------------------------------- LineElement(String lName, String strPoint, String endPoint, String ang, String bLine, String strPtMet, String strPar, String endPtMet, String endPar, String gName ) { this.lineName = lName; this.startPoint = strPoint; this.endPoint = endPoint; this.angle = ang; this.oldLineName = bLine; this.startPointMethod = strPtMet; this.startParam = strPar; this.endPointMethod = endPtMet; this.endParam = endPar; this.groupName = gName; } }
打印方法代码:
public void linkedHashMapTest (LinkedHashMap<String, MyNewGUI.GeoElement> linkedHashMap) { System.out.print("\n =================================================== \n "); for (Entry<String, MyNewGUI.GeoElement> entry : linkedHashMap.entrySet()) { System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue().toString()); } System.out.print(" =================================================== \n "); // 创建存储值的List List<GeoElement> list = new ArrayList< GeoElement>(linkedHashMap.values()); // 打印List System.out.println("List - " + list); }
解决方案
问题根源是Java默认的toString()方法只会输出类名+哈希码,要显示具体属性,必须在每个自定义类中重写toString()方法。
1. 重写GeoElement的toString()(可选,作为基类模板)
class GeoElement { String elemType = "Generic"; // 元素类型 @Override public String toString() { return "GeoElement{elemType='" + elemType + "'}"; } }
2. 重写PointElement的toString()
把点的名称和坐标全部拼接成可读字符串:
class PointElement extends GeoElement { final String elemType = "Point"; String pointName = ""; // 点名称 double pointCoord[] = {0.0, 0.0, 0.0}; // 点坐标 public PointElement(String pName, double px, double py, double pz) { this.pointName = pName; this.pointCoord[0] = px; this.pointCoord[1] = py; this.pointCoord[2] = pz; } @Override public String toString() { return "PointElement{" + "elemType='" + elemType + '\'' + ", pointName='" + pointName + '\'' + ", pointCoord=[" + pointCoord[0] + ", " + pointCoord[1] + ", " + pointCoord[2] + "]" + '}'; } }
3. 重写LineElement的toString()
包含线的所有属性:
class LineElement extends GeoElement { final String elemType = "Line"; String lineName = ""; // 线名称 String startPoint = ""; // 起点或锚点 String endPoint = ""; // 终点(仅两点线使用) String angle = ""; // 角度(度) String oldLineName = ""; // 基线名称 String startPointMethod = ""; // 起点生成方法 String startParam = ""; // 起点参数 String endPointMethod = ""; // 终点生成方法 String endParam = ""; // 终点参数 String groupName = ""; // 组名称 public LineElement(String lName, String strPoint, String endPoint, String ang, String bLine, String strPtMet, String strPar, String endPtMet, String endPar, String gName) { this.lineName = lName; this.startPoint = strPoint; this.endPoint = endPoint; this.angle = ang; this.oldLineName = bLine; this.startPointMethod = strPtMet; this.startParam = strPar; this.endPointMethod = endPtMet; this.endParam = endPar; this.groupName = gName; } @Override public String toString() { return "LineElement{" + "elemType='" + elemType + '\'' + ", lineName='" + lineName + '\'' + ", startPoint='" + startPoint + '\'' + ", endPoint='" + endPoint + '\'' + ", angle='" + angle + '\'' + ", oldLineName='" + oldLineName + '\'' + ", startPointMethod='" + startPointMethod + '\'' + ", startParam='" + startParam + '\'' + ", endPointMethod='" + endPointMethod + '\'' + ", endParam='" + endParam + '\'' + ", groupName='" + groupName + '\'' + '}'; } }
4. 原打印方法无需修改
现在运行linkedHashMapTest,输出会显示实例的具体属性,示例如下:
=================================================== Key: ZERO, Value: PointElement{elemType='Point', pointName='ZERO', pointCoord=[0.0, 0.0, 0.0]} =================================================== List - [PointElement{elemType='Point', pointName='ZERO', pointCoord=[0.0, 0.0, 0.0]}]
额外优化建议
你在子类中重新定义了elemType字段,这会隐藏基类的同名字段。如果想让基类的elemType被正确继承,建议去掉子类中的elemType,改为在构造方法中给基类字段赋值:
class PointElement extends GeoElement { String pointName = ""; double pointCoord[] = {0.0, 0.0, 0.0}; public PointElement(String pName, double px, double py, double pz) { this.elemType = "Point"; // 直接给基类字段赋值 this.pointName = pName; this.pointCoord[0] = px; this.pointCoord[1] = py; this.pointCoord[2] = pz; } }
这样可以避免字段隐藏问题,让基类的toString()也能正确获取elemType的值。
内容的提问来源于stack exchange,提问作者Edelweiss Monville
相关产品推荐
相关产品推荐

