Hashtable without keys?

C

cody

Hi I need a hashtable _without_ keys.
I simply want to put values in it and later check wheather these values
exist in the table, so I don't need keys.

table.Add(value);

if (table.Contains(value))

Is there any class for that?
 
J

Jochen Kalmbach

cody said:
Hi I need a hashtable _without_ keys.
I simply want to put values in it and later check wheather these values
exist in the table, so I don't need keys.

table.Add(value);

if (table.Contains(value))

Is there any class for that?

Array !?
CollectionBase !?


What is "value" !?

Has-Tables without "keys" is not possible.

--
Greetings
Jochen

Do you need a memory-leak finder ?
http://www.codeproject.com/tools/leakfinder.asp


Do you need daily reports from your server ?
http://sourceforge.net/projects/srvreport/
 
J

Jon Skeet [C# MVP]

cody said:
Hi I need a hashtable _without_ keys.
I simply want to put values in it and later check wheather these values
exist in the table, so I don't need keys.

table.Add(value);

if (table.Contains(value))

Is there any class for that?

In other words, you want a set :)

No, there are no classes in the System.Collections namespace
specifically for that. The easiest thing to do is use a Hashtable, and
use the same reference for the key and the value.

Of course, you could wrap all that up in your own Set class if you
wanted.
 
C

cody

Hi I need a hashtable _without_ keys.
In other words, you want a set :)

Thats exactly what I meant :)
No, there are no classes in the System.Collections namespace
specifically for that. The easiest thing to do is use a Hashtable, and
use the same reference for the key and the value.

Thats what I did, but I hoped to get a better solution.
Of course, you could wrap all that up in your own Set class if you
wanted.

Uuuh..work...

I hope .NET framwork 2.0 will bring us more collections.
Iam looking forward to see LinkedList, DoubleLinkedList, Set and so on, of
course with generics support :)
 
C

cody

VB.NET has linked lists!


Wonderful. Why has VB.NET linked lists while C# has not?
Aren't they using the same framework or is this one of the funny VB-only
extensions.
 
D

Daniel O'Connell [C# MVP]

cody said:
Thats exactly what I meant :)


Thats what I did, but I hoped to get a better solution.


Uuuh..work...

I hope .NET framwork 2.0 will bring us more collections.
Iam looking forward to see LinkedList, DoubleLinkedList, Set and so on, of
course with generics support :)

I still don't see the huge fuss over linked lists...I've needed a linked
list *once* since I stopped using plain C and was able to use vectors and
resizable arrays in all these neat new langauges, it took me maybe 20
minutes to write in C#...its not hard when you don't have to deal with
memory allocations. How often do you really think you need a linked list
and why? Does anyone have a reason that a seperate LinkedList class *has* to
exist in the base...is it really used that much? Various balanced trees,
sets, SkipLists I could see(generic of course, ;))...but I think a
LinkedList would be a waste of resources.
 
G

Gerry O'Brien [MVP]

I don't program in C# so I'm not sure why.

I know that VB has them because the course I developed for CompuCollege here
in Moncton teaches linked lists, stacks and queues.

I'm not sure why C# doesn't have them.
 
D

Daniel O'Connell [C# MVP]

Gerry O'Brien said:
I don't program in C# so I'm not sure why.

I know that VB has them because the course I developed for CompuCollege
here
in Moncton teaches linked lists, stacks and queues.

I'm curious, what class did you use? I know of no LinkedList class in any of
the existing runtime...Microsoft.VisualBasic.dll or otherwise. Or is it some
bit of language feature? I'm not too up to date with VB, but I don't recall
any built in Linked lists...
 
J

Jon Skeet [C# MVP]

Daniel O'Connell said:
I'm curious, what class did you use? I know of no LinkedList class in any of
the existing runtime...Microsoft.VisualBasic.dll or otherwise. Or is it some
bit of language feature? I'm not too up to date with VB, but I don't recall
any built in Linked lists...

I'm interested in this too. Of course, you can teach about linked lists
without there being one available in the standard library. It would be
easy to teach about linked lists in C# too. In fact, if you're teaching
the concept of a linked list, it would be fairly normal to show the
source code for such a beast anyway, at which point it's pretty much
irrelevant whether or not it's in the standard library.
 
C

cody

I still don't see the huge fuss over linked lists...I've needed a linked
list *once* since I stopped using plain C and was able to use vectors and
resizable arrays in all these neat new langauges, it took me maybe 20
minutes to write in C#...its not hard when you don't have to deal with
memory allocations. How often do you really think you need a linked list
and why? Does anyone have a reason that a seperate LinkedList class *has* to
exist in the base...is it really used that much? Various balanced trees,
sets, SkipLists I could see(generic of course, ;))...but I think a
LinkedList would be a waste of resources.


You know that inserting or removing items it an ArrayList causes all
succeeding items to shift in memory?
Also in a critical real time it cannot be that your ArrayList if it resizes
due to an addition of an item grows and copies itself in memory,
also if you have a total of 100 mb ram and your ArrayList is 30mb in size,
resizing will cause the ArrayList to grow to the double size and now you
have an
30mb ArrayList plus a 60mb ArrayList in ram simultanously.
 
G

Gerry O'Brien [MVP]

There isn't a class in the framework library but rather one that we created.
Here it is in case you would like to use it yourself.

Namespace MedianLinkList

Public Class LinkedListNode

Public objData As Object

Public Link As LinkedListNode

Public Sub New()

objData = "none" ' Set original node object to a value of none

Link = Nothing ' ensure link is not pointing to anything

End Sub

' this method will allow you to display the values in the linked list in a
messagebox

' it is only for display purposes and you would want to use another display
element

Public Sub DisplayList(ByVal lnLink As LinkedListNode)

If Not lnLink Is Nothing AndAlso lnLink.objData <> "none" Then

MessageBox.Show(lnLink.objData)

DisplayList(lnLink.Link)

End If

End Sub

' this method will allow you to add an item to the top of the list and will
update the

' remaining link pointers as necessary

Public Sub AddItemToTop(ByRef lnLink As LinkedListNode, ByVal Obj As Object)

If lnLink.objData = "none" Then

lnLink.objData = Obj

Exit Sub

End If

Dim lnTmpNode As New LinkedListNode

With lnTmpNode

..objData = Obj

..Link = lnLink

End With

lnLink = lnTmpNode

End Sub

' this method will add the values to the list in ascending order.
Alphabetically and numerically

Public Sub AddInOrder(ByRef lnLink As LinkedListNode, ByVal Obj As Object)

If lnLink.objData = "none" Then ' the list is empty

lnLink.objData = Obj

Exit Sub

End If

' list is not empty

Dim lnTmpNode As New LinkedListNode

lnTmpNode.objData = Obj

If Obj < lnLink.objData Then ' new first node

lnTmpNode.Link = lnLink

lnLink = lnTmpNode

Exit Sub

End If

Dim Pointer, TrailPointer As LinkedListNode

Pointer = lnLink.Link

TrailPointer = lnLink

Do While Not Pointer Is Nothing

' more to check

If Obj < Pointer.objData Then

' we found the spot

lnTmpNode.Link = Pointer

TrailPointer.Link = lnTmpNode

Exit Sub

Else

TrailPointer = Pointer

Pointer = Pointer.Link

End If

Loop

' if we get here, insert at end of list

lnTmpNode.Link = Nothing

TrailPointer.Link = lnTmpNode

End Sub

' this method allows us to remove an item from the list. We only remove
items if the list is not empty

' we will remove the items from the end of the list to the beginning until
we have nothing left

Public Sub Remove(ByRef lnLink As LinkedListNode)

If lnLink.objData = "none" Then

Exit Sub

End If

If Not lnLink.Link Is Nothing Then

Dim Temp As LinkedListNode

Temp = lnLink

lnLink = lnLink.Link

Temp = Nothing

Else ' there is only one node left

lnLink.objData = "none"

End If

End Sub

End Class

End Namespace


--
Gerry O'Brien
Visual Developer .NET MVP
Visual Basic
 
D

Daniel O'Connell [C# MVP]

Ahh, I see. This same basic class could be written in C# without any
substantial changes(outside of syntax of course).
Gerry O'Brien said:
There isn't a class in the framework library but rather one that we
created.
Here it is in case you would like to use it yourself.

Namespace MedianLinkList

Public Class LinkedListNode

Public objData As Object

Public Link As LinkedListNode

Public Sub New()

objData = "none" ' Set original node object to a value of none

Link = Nothing ' ensure link is not pointing to anything

End Sub

' this method will allow you to display the values in the linked list in a
messagebox

' it is only for display purposes and you would want to use another
display
element

Public Sub DisplayList(ByVal lnLink As LinkedListNode)

If Not lnLink Is Nothing AndAlso lnLink.objData <> "none" Then

MessageBox.Show(lnLink.objData)

DisplayList(lnLink.Link)

End If

End Sub

' this method will allow you to add an item to the top of the list and
will
update the

' remaining link pointers as necessary

Public Sub AddItemToTop(ByRef lnLink As LinkedListNode, ByVal Obj As
Object)

If lnLink.objData = "none" Then

lnLink.objData = Obj

Exit Sub

End If

Dim lnTmpNode As New LinkedListNode

With lnTmpNode

.objData = Obj

.Link = lnLink

End With

lnLink = lnTmpNode

End Sub

' this method will add the values to the list in ascending order.
Alphabetically and numerically

Public Sub AddInOrder(ByRef lnLink As LinkedListNode, ByVal Obj As Object)

If lnLink.objData = "none" Then ' the list is empty

lnLink.objData = Obj

Exit Sub

End If

' list is not empty

Dim lnTmpNode As New LinkedListNode

lnTmpNode.objData = Obj

If Obj < lnLink.objData Then ' new first node

lnTmpNode.Link = lnLink

lnLink = lnTmpNode

Exit Sub

End If

Dim Pointer, TrailPointer As LinkedListNode

Pointer = lnLink.Link

TrailPointer = lnLink

Do While Not Pointer Is Nothing

' more to check

If Obj < Pointer.objData Then

' we found the spot

lnTmpNode.Link = Pointer

TrailPointer.Link = lnTmpNode

Exit Sub

Else

TrailPointer = Pointer

Pointer = Pointer.Link

End If

Loop

' if we get here, insert at end of list

lnTmpNode.Link = Nothing

TrailPointer.Link = lnTmpNode

End Sub

' this method allows us to remove an item from the list. We only remove
items if the list is not empty

' we will remove the items from the end of the list to the beginning until
we have nothing left

Public Sub Remove(ByRef lnLink As LinkedListNode)

If lnLink.objData = "none" Then

Exit Sub

End If

If Not lnLink.Link Is Nothing Then

Dim Temp As LinkedListNode

Temp = lnLink

lnLink = lnLink.Link

Temp = Nothing

Else ' there is only one node left

lnLink.objData = "none"

End If

End Sub

End Class

End Namespace


--
Gerry O'Brien
Visual Developer .NET MVP
Visual Basic
 
D

Daniel O'Connell [C# MVP]

cody said:
You know that inserting or removing items it an ArrayList causes all
succeeding items to shift in memory?
Yes, I know, do you know that lookup time for an linked list is considerably
higher than an ArrayList? However, how often do you really insert or remove?
And how often is the whole thing big enough that it matters. When you
combine the issue with the memory problems below...its not nessecerily as
big a problem as you seem to think. In an array list, the cost of inserting,
adding, and removing incurs that lookup cost as well(by storing the tail or
adding to the head you can mitigate the cost of adding).
Let us consider(there may be off by one errors here, I don't have time to
verify the exactness right now):
assuming the arraylist is big enough to hold the items(by default it should
be at 64 at this point, I think)
an ArrayListof 40 objects and a linked list of the same forty.
If I want to insert an object at index 20 I would:
for ArrayList:
base + 20*refSize = index;
copy 20*refSize bytes to index+refSize;
copy refSize bytes to index;

for LinkedList


compare the link address to to null
if not null, then load node at link address and
repeat 19 times
copy thisNode next address to lastNode next address
copy lastNode next address to thisNode address


Neither one is really that much more efficent than the other. Some tricks
could be performed to *try* to speed up node lookups, but not without the
cost of complexity. Most of the really good tricks need to understand the
usage, which a general class can't match. Inserting in linked lists is much
more valuable when you are directly acessing the list than it is when you
try to use IList to work with the list. For small amounts of data, there
should be virtually no difference in insertion speed, for large amounts the
memory issues with LinkedLists I illustrate below is potentially a problem.
Also in a critical real time it cannot be that your ArrayList if it
resizes
due to an addition of an item grows and copies itself in memory,

This point is moot, as you really shouldn't be using .NET in critical
realtime situations anyway, atleast in its current form. The garbage
collector is unpredictable and may freeze threads for unpredictable amounts
of time while it moves an unpredictable amount of memory around...how
exactly does that make an array resize something to worry about?
also if you have a total of 100 mb ram and your ArrayList is 30mb in size,
resizing will cause the ArrayList to grow to the double size and now you
have an
30mb ArrayList plus a 60mb ArrayList in ram simultanously.

If you are using a large ArrayList, you should pre-define the size instead
of letting it grow. Anyway, lets do some math here, a linked list of
integers, consider it LinkedList<int>, using 30 meg of integer data as the
store amount:
integers: 7864320 integers * 4bytes an integer = 31,457,280 bytes or 30 megs
node references: 7864320 node references * 4bytes a reference = 31,457,280
bytes or 30 megs
size of the combined nodes: 62,914,560 bytes or 60 megs
node object headers(the .NET runtime headers, pretty sure this is 8 bytes):
7864320 * 8 = 62,914,560 bytes or 60 megs
grand total: 125,829,120 bytes or 120 meg for 30meg of data storage. this
would be larger still on 64 bit hardware and\or you use a doubly linked
list.
This is higher than the combined 90 meg of array data in an
List<int>(ArrayList would exhibit worse problems because it would box the
ints, forming references to them and extra object headers, a non-generics
enabled, object based linked list would exhibit the same issue. In effect
you end up with an extra 12 bytes per integer, even ontop of the costs of
LinkedList as it stands). 30 of that 90 will be collected in fairly short
order, but the 120 of the linked list will stay until the list is done with.

The end result is that storing an object in a LinkedList will always take up
atleast an extra 12 bytes ontop of the memory cost of the object vs storing
the same object in an array or an ArrayList. Trading off that extra space
for trees or skiplists...something that will reduce lookup time or add
hiearchy is one thing, but to achieve the singular effect of speading up
insertions in some cases is not generally something I'm interested in. I
know that linked lists are sometimes valuable...but I really don't believe
that they are so important that a generic implementation needs to exist in
the BCL. I have the serious concern that by adding LinkedLists to .NET,
people are going to start using them on this concept of "inserts are so much
faster" without considering the, IMHO substantial, downfalls of a
LinkedList.
--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
 
J

Jon Skeet [C# MVP]

Gerry O'Brien said:
There isn't a class in the framework library but rather one that we created.

That's really not the same as your previous claim that "VB.NET has
linked lists!" though, is it?
 
C

cody

Yes, I know, do you know that lookup time for an linked list is
considerably
higher than an ArrayList?

Therefore you should not use InsertAt or IndexOf, instead you should
remember the Nodes where you want to insert so
you don't have to traverse the list every time. Inserting at head or tail is
cheap as well because theses Nodes are always available.
However, how often do you really insert or remove?

Very often.
And how often is the whole thing big enough that it matters.

Often. Already 40 elements can be a lot when removing and inserting in an
arraylist vs linkedlist.
If you are using a large ArrayList, you should pre-define the size instead
of letting it grow. Anyway, lets do some math here, a linked list of
integers, consider it LinkedList<int>, using 30 meg of integer data as the
store amount:
integers: 7864320 integers * 4bytes an integer = 31,457,280 bytes or 30 megs
node references: 7864320 node references * 4bytes a reference = 31,457,280
bytes or 30 megs
size of the combined nodes: 62,914,560 bytes or 60 megs
node object headers(the .NET runtime headers, pretty sure this is 8 bytes):
7864320 * 8 = 62,914,560 bytes or 60 megs
grand total: 125,829,120 bytes or 120 meg for 30meg of data storage. this
would be larger still on 64 bit hardware and\or you use a doubly linked
list.
This is higher than the combined 90 meg of array data in an
List<int>(ArrayList would exhibit worse problems because it would box the
ints, forming references to them and extra object headers, a non-generics
enabled, object based linked list would exhibit the same issue. In effect
you end up with an extra 12 bytes per integer, even ontop of the costs of
LinkedList as it stands). 30 of that 90 will be collected in fairly short
order, but the 120 of the linked list will stay until the list is done with.

The end result is that storing an object in a LinkedList will always take up
atleast an extra 12 bytes ontop of the memory cost of the object vs storing
the same object in an array or an ArrayList. Trading off that extra space
for trees or skiplists...something that will reduce lookup time or add
hiearchy is one thing, but to achieve the singular effect of speading up
insertions in some cases is not generally something I'm interested in. I
know that linked lists are sometimes valuable...but I really don't believe
that they are so important that a generic implementation needs to exist in
the BCL. I have the serious concern that by adding LinkedLists to .NET,
people are going to start using them on this concept of "inserts are so much
faster" without considering the, IMHO substantial, downfalls of a
LinkedList.

LinkedLists are certainly not useful for int values, but they are for larger
objects or structs (with generics using structs instead of objects in
LinkedLists can improve performance a lot).

The only problem with LinkedList in .NET is that the whole bunch of
references in a LinkedList slows GC down thats one of the reasons why they
left it out, I suppose.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top