Flex中ArrayCollection与Array的区别

日常工作中经常会用到如题的两种类型数据,但具体有什么区别并没有深究一二。今天特地整理分享下:
当Array的数据发生变化的时候,用它作为数据源的控件不能感知这种变化。
例如:myArray.push(“new value”); 这时,如果一个List用它作为dataProvider,List的列表中不会增加新加入的这个值。
而当ArrayCollection的数据发生变化的时候,能够通知控件发生变化。
例如:myArrayCollection.addItem(“new item”); 这时,如果一个控件List用它作为dataProvider,List列表中会增加一列内容
ArrayCollection继承ListCollectionView基类,而ListCollectionView实现接口ICollectionView,在Flex的类定义内属于[数据集],它提供更强大的检索、过滤、排序、分类、更新监控等功能。类似的类还有XMLListCollection。
这两者差别在于如果用Array作为dataProvider数据绑定时,无法获得组件更新,除非组件被重新绘制或创建,抑或是dataProvider重新被指定,而ArrayCollection的副本存储于ArrayCollection类的某个实例中,其特点是ArrayCollection类本身就具有数据同步的方法,当其中某一元素内容发生改变时会抛出数据改变的事件给使其为数据源的组件,进而组件进行数据更新。
Arraycollection的构造函数是:ArrayCollection(source:Array=null);
示例如下:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
      <mx:Script>
          <![CDATA[
              import mx.collections.ArrayCollection;
              [Bindable]
              public var myArray:Array=["北京","上海","深圳"];
              [Bindable]
              public var myCollection:ArrayCollection=new ArrayCollection(myArray);
              public function addCountryToArray(country:String):void{
                  myArray.push(country);
              }
              public function addCountryToCollection(country:String):void{
                  myCollection.addItem(country);
              }
          ]]>
      </mx:Script>
      <mx:TextInput id="countryTextInput" text="广州"/>
      <mx:Label text="Bound to Array (Raw Object)"/>
      <mx:Button click="addCountryToArray(countryTextInput.text)" label="Add Country to Array"/>
      <mx:List dataProvider="{myArray}" width="200"/>
      <mx:Label text="Bound to Collection"/>
      <mx:Button click="addCountryToCollection(countryTextInput.text)" label="Add Country to Collection"/>
      <mx:List dataProvider="{myCollection}" width="200"/>
</mx:Application>

ArrayCollection特点
ArrayCollection是flex中的数组集合类,它是很常用的,我们使用它时需要注意几个地方
(1)事件监听
ArrayCollection 可以为它注册一个集合改变的监听事件(CollectionEvent.COLLECTION_CHANGE),就是一旦 ArrayCollection数组改变就会触发Event,不是所有情况的改变都会触发改变事件,如果集合当中的对象属性没有被绑定,那么你改变它的对 象值也是不会触发事件的,在这种情况下你也许可能需要去将对象的属性进行绑定或者通过itemUpdated方法去管理对象值改变,除非集合的长度改变 了,事件才会被触发 。
(2)对象删除
ArrayCollection的对象删除方法 removeAll(),有这样一种情况,当你在过滤集合数据的时候,它并不会删除所有数据,而是删除全部过滤的数据,不符合过滤条件的数据就没被删除, 依然还在source中 。
(3)过滤函数
ArrayCollection有个 filterFunction过滤函数,就是可能集合中你只需要显示其中某几个对象,你将会需要根据对象条件筛选对象,那么你可能会用过滤函数,过滤函数 会将不符合条件的对象过滤出。来,但是ArrayCollection有个source属性是不会变的,它是个数组,所有源数据全在里面,尽管你去过滤,所 有对象都会一直存在其中
(4)排序
ArrayCollection还有一个sort属性是用来排序的,你可以为其指定排序字段,具体参考Sort类。

Array和ArrayCollection的比较
Array的优点:
1)Array的性能优于ArrayCollection,从测试结果平均看来,ArrayCollection的效率是随着object的数目呈线性下降的,而Array则是体现了优异的效率,在object增加的情况下,基本上没有太大的变化。所以如果在你需要遍历所有元素的情况下(比如说物理引擎,3D引擎等),Array是不错的选择
程序见附件1.
2) 后台JavaBean也用的是数组[]
3)for循环数组似乎比for each ArrayConllection看起来更“傻瓜化”
4) 给Array数组扩展长度,也可以变通实现,而且代价并不大
ArrayCollection的优点:
1)ArrayCollection 实现接口CollectionView,在 Flex 的类定义内属于[数据集],他提供更强大的检索、过滤、排序、分类、更新监控等功能。类似的类还有 XMLListCollection ;
2)用 array 在作为 dataProvider 绑定于 control 之上,就无法获得控件的更新(实际上效果是可以得到更新的),除非控件被重新绘制或者 data provider 被重新指定,而 Collection 则是将 array 的副本存储于 Collection 类的某个对象之中,其特点是 Collection 类本身就具备了确保数据同步的方法,例子如上面的代码片段;
3)对 ArrayCollection中的对象进行增加删除更新操作时ArrayCollection会产生事件,可以通过collectionchange(CollectionEvent.COLLECTION_CHANGE)事件监听。
所以对于数据绑定一般采用的是ArrayCollection,另外ArrayList也可以实现绑定功能,它是轻量级的ArrayCollection,不过比ArrayCollection缺少排序过滤等功能,实际开发中以需求为主。

下图为10000条数据测试结果:
性能测试比较
附:图表测试代码:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       frameRate="100" width="600" height="500">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            [Bindable]
            private var ds:ArrayCollection;
            private var array:Array;
            private var ac:ArrayCollection;

            public function loop(loopCount:uint):Object
            {
                array=null;
                ac=null;
                var begin:uint;
                var end:uint;
                var interval1:Number=0;
                var interval2:Number=0;
                var interval3:Number=0;
                var interval4:Number=0;
                var i:uint;
                // for array, insert to array
                i=0;
                array=new Array();
                begin=getTimer();
                for (i; i < loopCount; i++)
                {
                    array.push({test: "hello world"});
                }
                end=getTimer();
                interval1=end - begin;
                t1.text=interval1.toString() + " ms";
                //loop the array
                i=0;
                begin=getTimer();
                for (i; i < array.length; i++)
                {
                    array[i];
                }
                end=getTimer();
                interval3=end - begin;
                t3.text=interval3.toString() + " ms";
                /// for ac, insert to array collection
                i=0;
                ac=new ArrayCollection();
                begin=getTimer();
                for (i; i < loopCount; i++)
                {
                    ac.addItem({test: "helllo"});
                }
                end=getTimer();
                interval2=end - begin;
                t2.text=interval2.toString() + " ms";
                //loop the array collection
                i=0;
                begin=getTimer();
                for (i; i < ac.length; i++)
                {
                    ac.getItemAt(i);
                }
                end=getTimer();
                interval4=end - begin;
                t4.text=interval4.toString() + " ms";
                return {ct: loopCount, array_insert: interval1, ac_insert: interval2, array_loop: interval3, ac_loop: interval4};
            }

            private function autoLoop():void
            {
                ds=null;
                ds=new ArrayCollection();
                var i:uint=0;
                for (i; i < parseInt(count.text); i+=parseInt(count.text) > 100 ? parseInt(count.text) / 10 : 1)
                {
                    ds.addItem(loop(i));
                }
            }

            public function reset():void
            {
                t1.text="0";
                t2.text="0";
                t3.text="0";
                t4.text="0";
                count.text="1000";
                ds=null;
                ds=new ArrayCollection();
            }
        ]]>
    </fx:Script>
    <s:layout>
        <s:VerticalLayout paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10"/>
    </s:layout>
    <mx:ApplicationControlBar width="100%">
        <mx:Label text="插入条数:" fontSize="12" color="#0B333C" fontWeight="bold"/>
        <mx:TextInput width="98" text="1000" id="count"/>
        <mx:Button id="startBtn0" label="Test" click="autoLoop()"/>
        <mx:VRule height="15"/>
        <mx:Button label="reset" click="reset()"/>
    </mx:ApplicationControlBar>
    <mx:Panel width="100%" height="480" layout="horizontal" id="testBed" title="Array 与Array Collection的性能比较" fontSize="11" fontWeight="normal">
        <mx:Canvas width="100%" height="100%" id="main" borderStyle="none" autoLayout="false" horizontalScrollPolicy="off" fontSize="12">
            <mx:LineChart id="lc" x="8.5" y="133" width="463" height="306" showDataTips="true" dataProvider="{ds}" fontSize="12">
                <mx:horizontalAxis>
                    <mx:CategoryAxis dataProvider="{ds}" categoryField="ct" title="插入Object数目"/>
                </mx:horizontalAxis>
                <mx:verticalAxis>
                    <mx:LinearAxis id="la" minimum="-1" title="响应时间(毫秒)"/>
                </mx:verticalAxis>
                <mx:series>
                    <mx:LineSeries displayName="Array 插入耗时" yField="array_insert"/>
                    <mx:LineSeries displayName="ArrayCollection 插入耗时" yField="ac_insert"/>
                    <mx:LineSeries displayName="Array 遍历耗时" yField="array_loop"/>
                    <mx:LineSeries displayName="ArrayCollection 遍历耗时" yField="ac_loop"/>
                </mx:series>
            </mx:LineChart>
            <mx:HBox x="10" y="0" width="100%" height="134" horizontalAlign="left" verticalAlign="middle">
                <mx:Grid horizontalGap="1" borderColor="#C6C6C6" borderStyle="solid">
                    <mx:GridRow width="100%" height="100%">
                        <mx:GridItem width="86" height="100%">
                            <mx:Label text="毫秒(ms)" fontSize="12"/>
                        </mx:GridItem>
                        <mx:GridItem width="100%" height="100%" fontSize="12">
                            <mx:Label text="Array"/>
                        </mx:GridItem>
                        <mx:GridItem width="100%" height="100%" fontSize="12">
                            <mx:Label text="ArrayCollection"/>
                        </mx:GridItem>
                    </mx:GridRow>
                    <mx:GridRow width="100%" height="100%">
                        <mx:GridItem width="66" height="100%">
                            <mx:Label text="插入耗时" fontSize="12"/>
                        </mx:GridItem>
                        <mx:GridItem width="100%" height="100%">
                            <mx:Text text="0" width="80" id="t1" fontSize="12"/>
                        </mx:GridItem>
                        <mx:GridItem width="100%" height="100%">
                            <mx:Text text="0" id="t2" width="80" fontSize="12"/>
                        </mx:GridItem>
                    </mx:GridRow>
                    <mx:GridRow width="100%" height="100%">
                        <mx:GridItem width="100%" height="100%">
                            <mx:Label text="遍历耗时" fontSize="12"/>
                        </mx:GridItem>
                        <mx:GridItem width="100%" height="100%" fontSize="12">
                            <mx:Text text="0" width="80" id="t3"/>
                        </mx:GridItem>
                        <mx:GridItem width="100%" height="100%">
                            <mx:Text text="0" id="t4" width="80" fontSize="12"/>
                        </mx:GridItem>
                    </mx:GridRow>
                </mx:Grid>
                <mx:VRule height="73" width="3"/>
                <mx:Legend dataProvider="{lc}" width="100%" direction="vertical" fontSize="12" verticalGap="2" fontWeight="normal" fontStyle="normal" fontFamily="Verdana"/>
            </mx:HBox>
        </mx:Canvas>
    </mx:Panel>
</s:WindowedApplication>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值