ArrayList problem.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • GTi

    #1

    ArrayList problem.

    If I use:

    ArrayList TimeScale = new ArrayList();
    TimeScale.Capac ity = 1000;
    TimeScale[20]="test 1"

    The last line trow me an error:
    Index was out of range. Must be non-negative and less than the size of
    the collection.
    Parameter name: index

    Is there anything I don't get here?

  • Marc Gravell

    #2
    Re: ArrayList problem.

    ArrayList objects are not arrays - it is (essentially) a collection class;
    initially (in general - some ctors allow preloading) they are empty. The
    capacity is just the upper limit on what it can contain *without having to
    grow*. The Count is the current amount of data. If you call .Add() 5 times,
    then you will have 5 items, even if the capacity is 200, and [20] will fail.

    Are you sure you mean to use ArrayList? You could create (for example) a
    string array sized for 1000 items, and then [20] would work.

    Marc


    Comment

    • Jon Skeet [C# MVP]

      #3
      Re: ArrayList problem.

      GTi <tunlid@gmail.c om> wrote:[color=blue]
      > If I use:
      >
      > ArrayList TimeScale = new ArrayList();
      > TimeScale.Capac ity = 1000;
      > TimeScale[20]="test 1"
      >
      > The last line trow me an error:
      > Index was out of range. Must be non-negative and less than the size of
      > the collection.
      > Parameter name: index
      >
      > Is there anything I don't get here?[/color]

      Yes - the capacity isn't the same as the size. The capacity is how big
      the ArrayList can become without having to "grow" by copying all its
      data into a bigger backing array.

      --
      Jon Skeet - <skeet@pobox.co m>
      http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
      If replying to the group, please do not mail me too

      Comment

      • Kevin Spencer

        #4
        Re: ArrayList problem.

        An ArrayList is a Collection. Use the Add method to add an element to it.

        --
        HTH,

        Kevin Spencer
        Microsoft MVP
        ..Net Developer
        You can lead a fish to a bicycle,
        but it takes a very long time,
        and the bicycle has to *want* to change.

        "GTi" <tunlid@gmail.c om> wrote in message
        news:1137537623 .988637.220480@ o13g2000cwo.goo glegroups.com.. .[color=blue]
        > If I use:
        >
        > ArrayList TimeScale = new ArrayList();
        > TimeScale.Capac ity = 1000;
        > TimeScale[20]="test 1"
        >
        > The last line trow me an error:
        > Index was out of range. Must be non-negative and less than the size of
        > the collection.
        > Parameter name: index
        >
        > Is there anything I don't get here?
        >[/color]


        Comment

        • GTi

          #5
          Re: ArrayList problem.

          NOTE:
          This sample was just a example. In this samples I should use .add();
          But the a value is any value between 0 and maxitems and not all values
          in that range is used.

          Comment

          • GTi

            #6
            Re: ArrayList problem.

            (where did the sample go?)

            class TimeScale
            {
            public double TempSP = 0.0;
            public double TempER = 0.0;
            public double PresureSP = 0.0;
            public double PresureER = 0.0;
            }


            maxitems=1000; // from a calculation
            ArrayList TimeScale = new ArrayList(maxit ems);

            for(int a=0; a<maxitems; a++)
            {
            TimeScale gts = new GraphTimeScale( );
            gts.TempSP = somevalue2;
            gts.TempER = somevalue3;
            gts.PresureSP = somevalue4;
            gts.PresureER = somevalue5;
            TimeScale[a]=gts;

            // NOTE in this sample I should use .add(gts);
            but <a> can be any number from 0 to maxitems and not all indexes is
            filled.

            Comment

            • chris martin

              #7
              Re: ArrayList problem.

              > GTi <tunlid@gmail.c om> wrote:[color=blue]
              >[color=green]
              >> If I use:
              >>
              >> ArrayList TimeScale = new ArrayList();
              >> TimeScale.Capac ity = 1000;
              >> TimeScale[20]="test 1"
              >> The last line trow me an error:
              >> Index was out of range. Must be non-negative and less than the size
              >> of
              >> the collection.
              >> Parameter name: index
              >> Is there anything I don't get here?
              >>[/color]
              > Yes - the capacity isn't the same as the size. The capacity is how big
              > the ArrayList can become without having to "grow" by copying all its
              > data into a bigger backing array.
              >[/color]

              Most of us know that to be true. However, the docs would lead one to believe
              it *should* work like the OP expected.

              from ms-help://MS.VSCC.2003/MS.MSDNQTR.2003 FEB.1033/cpref/html/frlrfSystemColl ectionsArrayLis tClassCapacityT opic.htm

              "When the value of Capacity is set explicitly, the internal array is also
              reallocated to accommodate the specified capacity."


              Comment

              • GTi

                #8
                Re: ArrayList problem.

                One sample I have about 10000 items in a array.
                The short discription is like this:

                class TimeScale
                {
                public double TempSP = 0.0;
                public double TempER = 0.0;
                public double PresureSP = 0.0;
                public double PresureER = 0.0;
                public int StatusCode = 0;
                }

                maxitems=1000; // example
                ArrayList TimeScale = new ArrayList(maxit ems);
                for(int a=1; a<maxitems; a++)
                {
                GraphTimeScale gts = new GraphTimeScale( );
                gts.TempSP = somevalue1;
                gts.TempER = somevalue2;
                gts.PresureSP = somevalue3;
                gts.PresureER = somevalue4;
                gts.StatusCode = somevalue5;
                TimeScale[a] = gts;
                }


                Is there any other and better way of doing this?

                Comment

                • Jon Skeet [C# MVP]

                  #9
                  Re: ArrayList problem.

                  chris martin <chris_m|NOSPAM |@caliber|SPAM| web.com> wrote:[color=blue][color=green]
                  > > Yes - the capacity isn't the same as the size. The capacity is how big
                  > > the ArrayList can become without having to "grow" by copying all its
                  > > data into a bigger backing array.
                  > >[/color]
                  >
                  > Most of us know that to be true. However, the docs would lead one to believe
                  > it *should* work like the OP expected.
                  >
                  > from ms-help:<snip>
                  >
                  > "When the value of Capacity is set explicitly, the internal array is also
                  > reallocated to accommodate the specified capacity."[/color]

                  That doesn't suggest that it should have worked. That talks about the
                  size of the internal array, *not* the logical size of the ArrayList
                  itself.

                  --
                  Jon Skeet - <skeet@pobox.co m>
                  http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                  If replying to the group, please do not mail me too

                  Comment

                  • Jon Skeet [C# MVP]

                    #10
                    Re: ArrayList problem.

                    GTi <tunlid@gmail.c om> wrote:[color=blue]
                    > One sample I have about 10000 items in a array.
                    > The short discription is like this:
                    >
                    > class TimeScale
                    > {
                    > public double TempSP = 0.0;
                    > public double TempER = 0.0;
                    > public double PresureSP = 0.0;
                    > public double PresureER = 0.0;
                    > public int StatusCode = 0;
                    > }
                    >
                    > maxitems=1000; // example
                    > ArrayList TimeScale = new ArrayList(maxit ems);
                    > for(int a=1; a<maxitems; a++)
                    > {
                    > GraphTimeScale gts = new GraphTimeScale( );
                    > gts.TempSP = somevalue1;
                    > gts.TempER = somevalue2;
                    > gts.PresureSP = somevalue3;
                    > gts.PresureER = somevalue4;
                    > gts.StatusCode = somevalue5;
                    > TimeScale[a] = gts;
                    > }
                    >
                    >
                    > Is there any other and better way of doing this?[/color]

                    Yes - call the Add method instead of using the indexer. Note that that
                    will fill the ArrayList from index 0 rather than index 1 (you know
                    you're only adding maxitems-1 items in the above, don't you?).

                    --
                    Jon Skeet - <skeet@pobox.co m>
                    http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                    If replying to the group, please do not mail me too

                    Comment

                    • Jon Skeet [C# MVP]

                      #11
                      Re: ArrayList problem.

                      GTi <tunlid@gmail.c om> wrote:

                      <snip>
                      [color=blue]
                      > // NOTE in this sample I should use .add(gts);
                      > but <a> can be any number from 0 to maxitems and not all indexes is
                      > filled.[/color]

                      In that case I suggest you call Add enough times adding null elements,
                      then use the indexer to set the specific values you're interested in.

                      --
                      Jon Skeet - <skeet@pobox.co m>
                      http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                      If replying to the group, please do not mail me too

                      Comment

                      • Marc Gravell

                        #12
                        Re: ArrayList problem.

                        One leaps to mind: use an array!

                        In your example the required size is obviously fixed at 1000 (well, 999
                        actually but who's counting), and you aren't using any of the "bouns"
                        features of the ArrayList, so why not just use an array? i.e.
                        GraphTimeScale[].

                        This would have less overhead, and would give you better type safety. Note:
                        if you are using .Net 2.0, even if you can't use GraphTimeScale[] you might
                        want to consider replacing ArrayList with List<GraphTimeS cale>

                        Marc


                        Comment

                        • Marc Gravell

                          #13
                          Re: ArrayList problem.

                          As another thought: you say not all indexes are filled. How sparse is it?
                          20%? 80%?

                          If it is going to have any reasonable amount of emptyness, another option is
                          to use a HashTable, using the index as the key (and will be unique).
                          Functionally it would be very similar: access might be *slightly* slower
                          (due to having to look through the hash buckets), but it should still be
                          acceptable for most usage. If you are using 2.0 you could use
                          Dictionary<int, GraphTimeScale> which is the generic, type-safe version.

                          Marc


                          Comment

                          • GTi

                            #14
                            Re: ArrayList problem.


                            Marc Gravell wrote:[color=blue]
                            > As another thought: you say not all indexes are filled. How sparse is it?
                            > 20%? 80%?
                            >
                            > If it is going to have any reasonable amount of emptyness, another option is
                            > to use a HashTable, using the index as the key (and will be unique).
                            > Functionally it would be very similar: access might be *slightly* slower
                            > (due to having to look through the hash buckets), but it should still be
                            > acceptable for most usage. If you are using 2.0 you could use
                            > Dictionary<int, GraphTimeScale> which is the generic, type-safe version.
                            >
                            > Marc[/color]

                            It can have as low as 2 items in a 10000 list :|

                            I think I must redesign my function using HashTable or Dictionary.

                            Tx Marc

                            Comment

                            • Marc Gravell

                              #15
                              Re: ArrayList problem.

                              How about this then:

                              public class SomeClass { // class for test harness
                              public readonly int SomeField;
                              public SomeClass(int value) { SomeField = value; }
                              }
                              public class SparseArray<T> { // impersonates an array, but hashtable
                              implementation
                              private Dictionary<int, T> data;
                              public SparseArray() {
                              data = new Dictionary<int, T>();
                              }
                              public SparseArray(int capacity) {
                              data = new Dictionary<int, T>(capacity);
                              }
                              public IEnumerable<int > Indexes {
                              get { return data.Keys; }
                              }
                              public IEnumerable<T> Values {
                              get { return data.Values; }
                              }
                              public void RemoveAt(int index) {
                              data.Remove(ind ex);
                              }
                              public T this[int index] {
                              set { data[index] = value; }
                              get {
                              T value;
                              data.TryGetValu e(index, out value); // ignore ret val
                              return value;
                              }
                              }
                              }
                              static class Program { // test harness
                              [STAThread]
                              private static void Main() {
                              Random rand = new Random();
                              SparseArray<Som eClass> data = new SparseArray<Som eClass>();
                              // create a sparse "array" in a dictionary
                              // note that data[i] is **NOT** the position, rather the **key**
                              (hashtables do not have a strict position)
                              for (int i = 0; i < 2000; i += rand.Next(1,500 )) { // just to
                              make it interesting
                              data[i] = new SomeClass(rand. Next());
                              }

                              Console.WriteLi ne("Using indexer (exhaustive)");
                              for (int i = 0; i < 2000; i++) {
                              SomeClass value = data[i];
                              if(value != null)
                              Console.WriteLi ne("{0}: {1}",i,value.So meField);
                              }

                              Console.WriteLi ne("\"In use\" indexes only");
                              foreach (int i in data.Indexes) {
                              Console.WriteLi ne("{0}: {1}", i, data[i].SomeField);
                              }

                              Console.WriteLi ne("Values");
                              foreach (SomeClass value in data.Values) {
                              Console.WriteLi ne(value.SomeFi eld);
                              }
                              }

                              }


                              Comment

                              Working...