【问题标题】:Java, how to implement perl's arrays of hashes?Java,如何实现 perl 的哈希数组?
【发布时间】:2011-04-29 08:55:36
【问题描述】:

我对 Perl 的数据结构有很好的经验,我是从 java 开始的(在 Android 上)。我需要实现类似这些 perl 数据结构的东西:

$beacons = (
 {
   ssid => "north",
   bssid => "01:02:03:04:05:06",
 },
 {
   ssid => "east",
   bssid => "02:03:04:05:06:07",
 },
 {
   ssid => "south",
   bssid => "03:04:05:06:07:08",
 },
 {
   ssid => "west",
   bssid => "04:05:06:07:08:09",
 },
);

$points = (
 {
  id => "La Gioconda",
  rssi => {
   north => -55,
   east => -76,
   south => -64,
   west => -92,
  },
 },
 {
  id => "La Pietà",
  rssi => {
   north => -51,
   east => -60,
   south => -88,
   west => -59,
  },
 },
 ...
);

这些是静态结构(最终从磁盘上的 xml 文件中读取)。

如果它有任何用处,我正在实施一个本地(室内)定位系统,使用位于博物馆每个房间的 4 个角落的 4 个 wifi 信标的 rssi(信号强度)值的变化,以找到智能手机的位置。在运行时,我必须将 4 个 rssi 值(每个来自具有特定 ssid 和 bssid 的信标)与我的所有点结构进行比较,并找到最接近我的值的那个。

Java 中最好的构造是什么?我应该使用 HashMaps 吗?可以举个例子吗?

【问题讨论】:

    标签: android data-structures


    【解决方案1】:

    方法 1:
    您可以使用 Hashmap 来实现您的目标。

    Map<String,String> beacons = new HashMap<String,String>();
    beacons.put("ssid","north");
    beacons.put("bssid","01:02:03:04:05:06");
    System.out.println(beacons.get("ssid")); // Outputs "north"
    

    方法 2:
    如果您的数据来自 xml 文件,您可以使用 JAXB API (Java XML Binding) 来构建您的对象。

    假设我们有以下 XML 文件:beacons.xml

    <beacons>
       <beacon ssid="north">
          <bssid>01:02:03:04:05:06</bssid>
       </beacon>
       <beacon ssid="north">
          <bssid>02:03:04:05:06:07</bssid>
       </beacon>
    </beacons>
    

    类可以这样定义:

    beacons.java

    package com.mycompany;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class Beacons {
        @XmlElement(name = "beacon")
        public List<Beacon> beaconsList = new ArrayList<Beacon>();
    }
    

    beacon.java

    package com.mycompany;
    
    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class Beacon {
        @XmlAttribute
        private String ssid;
        @XmlElement
        private String bssid;
    
        public String getSsid() {
            return ssid;
        }
    
        public String getBssid() {
            return bssid;
        }
    }
    

    加载类的示例代码:

    package com.mycompany;
    import java.io.File;
    import java.util.List;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Unmarshaller;
    
    public class Main {
    
        public static void main(String args[]) {
            try {
                JAXBContext jc = JAXBContext.newInstance(Beacons.class);
                Unmarshaller unmarshaller = jc.createUnmarshaller();
    
                Beacons myBeacons = (Beacons) unmarshaller.unmarshal(new File("beacons.xml"));
    
                List<Beacon> beaconsList = myBeacons.beaconsList;
                for (int i = 0; i < beaconsList.size(); i++) {
                    Beacon a_beacon = beaconsList.get(i);
                    System.out.println("Beacon " + (i+1));
                    System.out.println("SSID   : " + a_beacon.getSsid());
                    System.out.println("BSSID  : " + a_beacon.getBssid());
                    System.out.println();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    --

    这是输出:

    
    Beacon 1
    SSID   : north
    BSSID  : 01:02:03:04:05:06
    
    Beacon 2
    SSID   : north
    BSSID  : 02:03:04:05:06:07
    

    【讨论】:

    • 是的,但是 HashMaps 对稍微复杂的“点”结构有用吗?我想他们不是……
    • @Marcos 我通过使用 JAXB API(Java Xml 绑定)添加了第二种方法
    • 抱歉,我无法在 Eclipse 中解析“import javax.xml.bind.JAXBContext”:我确实将“com.viewstreet.java.eclipse.jaxbplugin_0.1.0”目录复制到了 Eclipse 的插件目录,重新启动 Eclipse,但我不断收到“无法解析导入 javax.xml.bind”...
    • @Marcos 你用的是哪个版本的java?检查 JRE 系统库是否在您的构建路径中(默认添加到 Eclipse 中的每个新 Java 项目中)。 javax.xml.bind.JAXBContext 应该位于rt.jar 与 java 6.
    【解决方案2】:

    Java 中最好的构造是什么?

    如果您的数据结构良好,为什么还要使用通用容器?

    如果您将这些定义良好的结构包装到它们自己的 Java 类中,您的代码会更高效。

    这些类的实现当然需要代码,但是后续使用这些结构会容易得多,而不必使用hash.get(key)hash.put(key, value) 样式访问器。

    【讨论】:

    • 你能举一个简单的例子说明如何实现“points”类吗?
    【解决方案3】:

    简单的值对象:

    public class Beacon {
        private String ssid;
        private String bssid;
    
        public Beacon(String ssid, String bssid) {
            this.ssid = ssid;
            this.bssid = bssid;
        }
    
        public String getSsid() {
            return ssid;
        }
    
        public String getBssid() {
            return bssid;
        }
    }
    
    public class Point {
        private String id;
        private Rssi rssi;
    
        public Point(String id, Rssi rssi) {
            this.id = id;
            this.rssi = rssi;
        }
    
        public String getId() {
            return id;
        }
    
        public Rssi getRssi() {
            return rssi;
        }
    }
    
    public class Rssi {
        private int north;
        private int east;
        private int south;
        private int west;
    
        public Rssi(int north, int east, int south, int west) {
            this.north = north;
            this.east = east;
            this.south = south;
            this.west = west;
        }
    
        public int getNorth() {
            return north;
        }
    
        public int getEast() {
            return east;
        }
    
        public int getSouth() {
            return south;
        }
    
        public int getWest() {
            return west;
        }
    }
    

    【讨论】:

    • 我最喜欢这种方法。你能举个例子来进行比较:即:有4个rssi值,找到最近的点id?
    • 你能告诉我使用什么算法或者我需要发明一个吗?似乎需要有很大的错误余地。如果一个或两个信标或 wifi 接收一般受损怎么办?
    【解决方案4】:
    private static final Map<String, String> BEACONS = new HashMap<String, String>();
    beacons.put("north", "01:02:03:04:05:06");
    ...
    

    private 在这里的意思是,除了你的类之外,没有实体可以看到这个 Map。 static 意味着它为此类创建一次,而不是每次创建对象时。此外,Java 命名约定假定您将 constatns 命名为大写。

    阅读更多关于 HashMaps 的 here

    【讨论】:

    • 是的,但是 HashMaps 对稍微复杂的“点”结构有用吗?我想他们不是……
    • 是的,他们是。只需在值位置使用 Point 而不是 String。
    猜你喜欢
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 2011-01-19
    • 2011-07-02
    • 2020-07-19
    • 1970-01-01
    相关资源
    最近更新 更多