【问题标题】:In AS3, where do you draw the line between Dictionary and ArrayCollection?在 AS3 中,Dictionary 和 ArrayCollection 之间的界限在哪里?
【发布时间】:2012-12-03 21:10:16
【问题描述】:

基本上,我一直在我的程序中使用一个 Dictionary 对象,它基本上将整数作为其键,并将 RTMFP 对等 ID 存储在适当的位置。每个 int 都是唯一的,代表一个用户。

现在我需要对此进行扩展,其中用户由 int 和布尔值的组合来标识,有点像这样:

private var m_iUID:int;
private var m_blnIsCurrent:Boolean;

只有这两者之间的组合才能真正唯一地标识用户。话虽这么说,我正要使用一个由此制成的新类作为字典键;但后来我突然想到,我可以不这样做,而是将对等 ID 添加到类定义中并将 Dictionary 对象转换为 ArrayCollection:

private var m_iUID:int;
private var m_blnIsCurrent:Boolean;
public var m_strNearID:String;

所以现在我想知道在这种情况下哪个更好。这个问题引出了一个更大的问题:一般来说,您在哪里真正划定这两种集合类型之间的界限?毕竟它们突然开始看起来并没有那么不同,除非你试图避免弄乱类定义。我想我真的在就具体情况和一般问题征求意见。谢谢!

【问题讨论】:

    标签: actionscript-3 apache-flex dictionary containers arraycollection


    【解决方案1】:

    ArrayCollection 只是 Array 的包装器,仅在 Flex 中可用。

    在 AS3 中,您确实有 3 种基本哈希表类型:数组、对象和字典。您可以根据要使用的键类型选择使用哪一个:整数、字符串或对象引用。数组会将任何键转换为 int,Object 会将任何键转换为字符串。 Dictionary 的作用类似于字符串键的对象(并将 primitives 转换为字符串),但它真正擅长的是使用对象 references 作为键。

    如果您想使用单个 int 作为唯一键,请使用数组。如果要使用单个字符串作为唯一键,请使用对象。如果您想使用对象引用作为唯一键,请使用字典。

    在您的情况下,您可能应该在“key”类上使用 Object 和自定义 toString() 方法。这是因为您想使用原始值的组合(不是对象引用)作为唯一键。没有办法在本地执行此操作,因此您必须将这些值作为单个字符串混合在一起。对象是字符串键最好(最快)的哈希表,所以这是你应该使用的集合。

    例子:

    class User {
        private var m_iUID:int;
        private var m_blnIsCurrent:Boolean;
        public var m_strNearID:String;
        public function User(UID:int, IsCurrent:Boolean) {
            m_iUID = UID;
            m_blnIsCurrent = IsCurrent;
        }
    
        // Custom toString to mash together primitives
        public function toString() {
            return m_iUID.toString() + "-" + (m_blnIsCurrent ? "1" : "0");
        }
    }
    
    // Later:
    var allUsers:Object = {}
    var user1:User = new User(231049, true);
    var user2:User = new User(0x2309, false);
    
    // Implicitly calls toString():
    allUsers[user1] = "User 1";
    allUsers[user2] = "User 2";
    
    // All of the following will successfully retrieve the value for user1 ("User 1"):
    // ONLY the first would work if allUsers was a Dictionary
    trace(allUsers[user1]);
    trace(allUsers[user1.toString()]); 
    trace(allUsers["231049-1"]); 
    trace(allUsers[new User(231049, true)]); 
    

    【讨论】:

      【解决方案2】:

      DictionaryArrayCollection 有一些重要的区别:

      • Dictionary 将对象映射到其他对象,而 ArrayCollection 只是对象列表。
      • ArrayCollection 仅适用于 Flex,因此无法在通用 AS3 项目中使用。

      你应该使用哪一个真的取决于你在你的应用程序中需要什么:

      • 您是否会在其他地方使用“身份”对象(带有用户 ID 和“当前”),而没有关联的对等 ID?在这种情况下,将其设为单独的 Identity 类左右,并使用 DictionaryIdentity 实例映射到对等 ID。
      • 您是否需要根据身份执行查找?换句话说,你需要问“哪个peer id与这个身份相关联?”。如果是这样,请再次使用 Dictionary + Identity,以避免循环遍历列表。

      我确信还有更多考虑因素,但这些应该可以帮助您入门。

      【讨论】:

      • 想一想,仅仅因为两个对象中的值相等并不意味着这两个对象相等 - 这可能会与字典混淆。我该如何解决这个问题?
      • @Panzercrisis 查看我的回答,它解决了这个确切的问题。
      • 是的,当使用Dictionary 时,您的应用必须确保在后续的gets/sets 中使用Identity 的相同实例(或左右)。在 f.e.由于equals()hashCode(),Java 这不是必需的,但不幸的是Dictionary 只使用严格相等(===)或“引用相等”。
      • @Torious 请注意术语——您是要与 Java 还是 JavaScript 进行比较?此外,使用引用相等是Dictionary 存在的全部原因,否则您将只使用Object 类型,它实际上是一个字符串键控哈希表。
      • @jmh_gr 我指的是 Java 以及 Hashtable 实现通常如何使用 Object.hashCode()Object.equals()。 Java 中的默认 equals() 实现也是引用相等,这使得 Java 的 Hashtable 基本上是 AS3 的 Dictionary 的“超级实现”...您的 Object 方法是一个很好的解决方法(并且可能是AS3),但 Java 的Hashtable 仍然更方便,因为没有摆弄String 键(或将toString() 用于意外目的)。
      猜你喜欢
      • 2011-06-13
      • 2014-08-05
      • 1970-01-01
      • 2010-09-15
      • 2011-03-30
      • 2011-01-27
      • 1970-01-01
      • 2011-11-03
      • 2016-04-07
      相关资源
      最近更新 更多