Qual è l'equivalente di un LinkedHashSet (Java) in C#?Qual è l'equivalente di LinkedHashSet (Java) in C#?
risposta
ho completato i metodi non finiti e, in generale lucido la classe che 'achitaka-san' postato.
public class LinkedHashSet<T> : ISet<T> {
private readonly IDictionary<T, LinkedListNode<T>> dict;
private readonly LinkedList<T> list;
public LinkedHashSet(int initialCapacity) {
this.dict = new Dictionary<T,LinkedListNode<T>>(initialCapacity);
this.list = new LinkedList<T>();
}
public LinkedHashSet() {
this.dict = new Dictionary<T,LinkedListNode<T>>();
this.list = new LinkedList<T>();
}
public LinkedHashSet(IEnumerable<T> e) : this() {
addEnumerable(e);
}
public LinkedHashSet(int initialCapacity, IEnumerable<T> e) : this(initialCapacity) {
addEnumerable(e);
}
private void addEnumerable(IEnumerable<T> e) {
foreach (T t in e) {
Add(t);
}
}
//
// ISet implementation
//
public bool Add(T item) {
if (this.dict.ContainsKey(item)) {
return false;
}
LinkedListNode<T> node = this.list.AddLast(item);
this.dict[item] = node;
return true;
}
public void ExceptWith(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in other) {
Remove(t);
}
}
public void IntersectWith(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
T[] ts = new T[Count];
CopyTo(ts, 0);
foreach (T t in ts) {
if (!System.Linq.Enumerable.Contains(other, t)) {
Remove(t);
}
}
}
public bool IsProperSubsetOf(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
int contains = 0;
int noContains = 0;
foreach (T t in other) {
if (Contains(t)) {
contains++;
} else {
noContains++;
}
}
return contains == Count && noContains > 0;
}
public bool IsProperSupersetOf(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
int otherCount = System.Linq.Enumerable.Count(other);
if (Count <= otherCount) {
return false;
}
int contains = 0;
int noContains = 0;
foreach (T t in this) {
if (System.Linq.Enumerable.Contains(other, t)) {
contains++;
} else {
noContains++;
}
}
return contains == otherCount && noContains > 0;
}
public bool IsSubsetOf(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in this) {
if (!System.Linq.Enumerable.Contains(other, t)) {
return false;
}
}
return true;
}
public bool IsSupersetOf(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in other) {
if (!Contains(t)) {
return false;
}
}
return true;
}
public bool Overlaps(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in other) {
if (Contains(t)) {
return true;
}
}
return false;
}
public bool SetEquals(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
int otherCount = System.Linq.Enumerable.Count(other);
if (Count != otherCount) {
return false;
}
return IsSupersetOf(other);
}
public void SymmetricExceptWith(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
T[] ts = new T[Count];
CopyTo(ts, 0);
HashSet<T> otherList = new HashSet<T>(other);
foreach (T t in ts) {
if (otherList.Contains(t)) {
Remove(t);
otherList.Remove(t);
}
}
foreach (T t in otherList) {
Add(t);
}
}
public void UnionWith(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in other) {
Add(t);
}
}
//
// ICollection<T> implementation
//
public int Count {
get {
return this.dict.Count;
}
}
public bool IsReadOnly {
get {
return this.dict.IsReadOnly;
}
}
void ICollection<T>.Add(T item) {
Add(item);
}
public void Clear() {
this.dict.Clear();
this.list.Clear();
}
public bool Contains(T item) {
return this.dict.ContainsKey(item);
}
public void CopyTo(T[] array, int arrayIndex) {
this.list.CopyTo(array, arrayIndex);
}
public bool Remove(T item) {
LinkedListNode<T> node;
if (!this.dict.TryGetValue(item, out node)) {
return false;
}
this.dict.Remove(item);
this.list.Remove(node);
return true;
}
//
// IEnumerable<T> implementation
//
public IEnumerator<T> GetEnumerator() {
return this.list.GetEnumerator();
}
//
// IEnumerable implementation
//
IEnumerator IEnumerable.GetEnumerator() {
return this.list.GetEnumerator();
}
}
usings richiesti:
using System;
using System.Collections;
using System.Collections.Generic;
Attenzione: La classe è in gran parte non testato, in particolare ai metodi Iset. Utilizzare a proprio rischio.
Spero che qualcuno lo trovi utile. :)
Non esiste un equivalente diretto in C#. La classe appropriata da utilizzare dipende dal comportamento desiderato. La classe HashSet
preserverà l'unicità degli elementi. Potresti anche voler dare un'occhiata a SortedSet
e SortedDictionary
.
Non esiste una classe in C# che combini una lista collegata con unicità richiesta in una struttura di dati Set, quindi se avete bisogno di entrambi i comportamenti, allora dovrete creare il vostro.
Ho implementato brevemente un HashSet
che garantisce l'ordine di inserimento. Utilizza lo Dictionary
per cercare gli articoli e lo LinkedList
per conservare l'ordine. Tutti e tre gli inserimenti, la rimozione e la ricerca funzionano ancora in O (1).
public class OrderedSet<T> : ISet<T>
{
private readonly IDictionary<T, LinkedListNode<T>> m_Dictionary;
private readonly LinkedList<T> m_LinkedList;
public OrderedSet()
{
m_Dictionary = new Dictionary<T, LinkedListNode<T>>();
m_LinkedList = new LinkedList<T>();
}
public bool Add(T item)
{
if (m_Dictionary.ContainsKey(item)) return false;
var node = m_LinkedList.AddLast(item);
m_Dictionary.Add(item, node);
return true;
}
void ICollection<T>.Add(T item)
{
Add(item);
}
public void Clear()
{
m_LinkedList.Clear();
m_Dictionary.Clear();
}
public bool Remove(T item)
{
LinkedListNode<T> node;
bool found = m_Dictionary.TryGetValue(item, out node);
if (!found) return false;
m_Dictionary.Remove(item);
m_LinkedList.Remove(node);
return true;
}
public int Count
{
get { return m_Dictionary.Count; }
}
public IEnumerator<T> GetEnumerator()
{
return m_LinkedList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Contains(T item)
{
return m_Dictionary.ContainsKey(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
m_LinkedList.CopyTo(array, arrayIndex);
}
public virtual bool IsReadOnly
{
get { return m_Dictionary.IsReadOnly; }
}
public void UnionWith(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public void IntersectWith(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public void ExceptWith(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool IsSubsetOf(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public void SymmetricExceptWith(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool IsSupersetOf(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool IsProperSupersetOf(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool IsProperSubsetOf(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool Overlaps(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool SetEquals(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
private static Exception GetNotSupportedDueToSimplification()
{
return new NotSupportedException("This method is not supported due to simplification of example code.");
}
}
HashSet fa il lavoro perché è praticamente equivalente a LinkedHashSet in Java. HashSet è supportato da un elenco collegato, anche se i documenti non dichiarano esplicitamente che conserva l'ordine o che è supportato da un elenco collegato basato su array. È possibile vedere da the source code l'implementazione è un LinkedHashSet.
I duplicati non sono consentiti proprio come Java LinkedHashSet. L'unica differenza tra questo e LinkedHashSet è che se rimuovi qualcosa dal set, contrassegna solo l'elemento come libero nell'array, e quindi aggiungendo un elemento dopo un remove() riempie gli slot di array vuoti prima di "accodare". Il modo per aggirare questo è chiamare il metodo TrimExcess(). Pertanto, anche se non è esattamente la stessa in molti casi d'uso, ad es. serializza e deserializza e per insiemi effettivamente immutabili una volta creato funziona alla grande.
È sempre possibile eseguire la sottoclasse e l'override di remove() per chiamare sempre TrimExcess() per ottenere lo stesso comportamento. E puoi dare un nome alla classe LinkedHashSet per chiarezza!
using System;
using System.Collections.Generic;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
String[] crew = {"Spock", "Kirk", "Bones", "Picard", "Uhura", "Chekov"};
HashSet<String> linkedHashSet = new HashSet<String>(crew);
// Show order is preserved
foreach(String value in linkedHashSet){
Console.Write(value); Console.Write(" ");
}
// Remove from the middle
linkedHashSet.Remove("Picard");
Console.WriteLine();
foreach(String value in linkedHashSet){
Console.Write(value); Console.Write(" ");
}
// Add it back but it is back in the middle not the end
linkedHashSet.Add("Picard");
Console.WriteLine();
foreach(String value in linkedHashSet){
Console.Write(value); Console.Write(" ");
}
// Remove and trim then add
linkedHashSet.Remove("Picard");
linkedHashSet.TrimExcess();
linkedHashSet.Add("Picard");
Console.WriteLine();
foreach(String value in linkedHashSet){
Console.Write(value); Console.Write(" ");
}
Console.WriteLine();
}
}
}
uscita:
Spock Kirk Bones Picard Uhura Chekov
Spock Kirk Bones Uhura Chekov
Spock Kirk Bones Picard Uhura Chekov
Spock Kirk Bones Uhura Chekov Picard
- 1. Java LinkedHashSet iterazione all'indietro
- 2. Ordinamento di LinkedHashSet
- 3. Qual è l'equivalente C# di Java DecimalFormat?
- 4. LinkedHashSet o ArrayList
- 5. qual è l'equivalente C# di static {...} in Java?
- 6. Qual è l'equivalente dell'accesso predefinito (pacchetto) di Java in C#?
- 7. Qual è l'equivalente C# /. NET di BufferedInputStream (in Java)?
- 8. qual è il C# equivalente di Iterator in Java
- 9. Qual è l'equivalente di C++ 11 dell'istanza di Java di
- 10. Qual è l'equivalente Objective-C di parseInt() di Java?
- 11. Qual è l'equivalente Java di C# "Contesto logico di chiamata"
- 12. Qual è la versione C++ di ArrayList di Java
- 13. Qual è l'equivalente di C# a Throwable di Java?
- 14. Qual è la versione C# equivalente di Java Webdriver @Findby?
- 15. Qual è l'uso di hashcode in Java?
- 16. Qual è Vtable in C++
- 17. Qual è l'equivalente C# di java.util.regex?
- 18. Qual è il significato di "==" in C?
- 19. Qual è lo scopo di :: in C#?
- 20. Qual è l'equivalente di bigint in C#?
- 21. Qual è l'uso di _start() in C?
- 22. Qual è l'equivalente di new/delete di C++ in C?
- 23. Qual è l'equivalente dei caratteri jolly Java nei generici C#
- 24. Qual è l'equivalente Java per il seguente codice C#?
- 25. qual è la dimensione della variabile di riferimento in java
- 26. Qual è il costo dell'utilizzo di eccezioni in Objective-C?
- 27. Qual è l'equivalente di java di ManualResetEvent?
- 28. Thread.interrupt() in Java: qual è il punto?
- 29. Intervalli in Java, qual è l'approccio migliore?
- 30. Qual è l'uso dell'interfaccia clonabile in java?
Sarà bene se si descrivere cosa LinkedHashSet fare :) – demas
E 'un set che mantiene l'ordine di inserimento. Usa una lista di supporto per farlo. – duffymo
possibile duplicato di [Perché HashSet non è impostato in C#?] (Http://stackoverflow.com/questions/1023697/why-have-hashset-but-not-set-in-c) – duffymo