網站首頁 編程語言 正文
文章目錄
- 特殊的集合
- BitArray 類
- BitVector32 結構
- 可觀察的集合
- 不變的集合
- 并發集合
特殊的集合
BitArray 類
BitArray類是一個引用類型,它包含一個int數組,其中每32位使用一個新整數。
public static class BitArrayExtensions
{
public static string GetBitsFormat(this BitArray bits)
{
var sb = new StringBuilder();
for (int i = bits.Length - 1; i >= 0; i--)
{
sb.Append(bits[i] ? 1 : 0);
if (i != 0 && i % 4 == 0)
{
sb.Append("_");
}
}
return sb.ToString();
}
}
class Program
{
static void Main()
{
var bits1 = new BitArray(9);
bits1.SetAll(true);
bits1.Set(1, false);
bits1[5] = false;
bits1[7] = false;
Console.Write("initialized: ");
Console.WriteLine(bits1.GetBitsFormat());
Console.Write("not ");
Console.Write(bits1.GetBitsFormat());
bits1.Not();
Console.Write(" = ");
Console.WriteLine(bits1.GetBitsFormat());
var bits2 = new BitArray(bits1);
bits2[0] = true;
bits2[1] = false;
bits2[4] = true;
Console.Write($"{bits1.GetBitsFormat()} OR {bits2.GetBitsFormat()}");
Console.Write(" = ");
bits1.Or(bits2);
Console.WriteLine(bits1.GetBitsFormat());
Console.Write($"{bits2.GetBitsFormat()} AND {bits1.GetBitsFormat()}");
Console.Write(" = ");
bits2.And(bits1);
Console.WriteLine(bits2.GetBitsFormat());
Console.Write($"{bits1.GetBitsFormat()} XOR {bits2.GetBitsFormat()}");
bits1.Xor(bits2);
Console.Write(" = ");
Console.WriteLine(bits1.GetBitsFormat());
Console.ReadLine();
}
}
BitVector32 結構
如果事先知道需要的位數,就可以使用BitVector32結構替代BitArray類。BitVector32結構效率較高,因為 它是一個值類型,在整數棧上存儲位。一個整數可以存儲32位。如果需要更多的位,就可以使用多個BitVector32 值或BitArray類。BitArray類可以根據需要增大,但BitVector32結構不能。
public static class BinaryExtensions
{
public static string AddSeparators(this string number) =>
number.Length <= 4 ? number :
string.Join("_",
Enumerable.Range(0, number.Length / 4)
.Select(i => number.Substring(startIndex: i * 4, length: 4)).ToArray());
public static string ToBinaryString(this int number) =>
Convert.ToString(number, toBase: 2).AddSeparators();
}
class Program
{
static void Main()
{
// create a mask using the CreateMask method
var bits1 = new BitVector32();
int bit1 = BitVector32.CreateMask();
int bit2 = BitVector32.CreateMask(bit1);
int bit3 = BitVector32.CreateMask(bit2);
int bit4 = BitVector32.CreateMask(bit3);
int bit5 = BitVector32.CreateMask(bit4);
bits1[bit1] = true;
bits1[bit2] = false;
bits1[bit3] = true;
bits1[bit4] = true;
bits1[bit5] = true;
Console.WriteLine(bits1);
// create a mask using an indexer
bits1[0xab_cdef] = true;
Console.WriteLine();
int received = 0x79ab_cdef;
BitVector32 bits2 = new BitVector32(received);
Console.WriteLine(bits2);
// sections: FF EEE DDD CCCC BBBBBBBB
// AAAAAAAAAAAA
BitVector32.Section sectionA = BitVector32.CreateSection(0xfff);
BitVector32.Section sectionB = BitVector32.CreateSection(0xff, sectionA);
BitVector32.Section sectionC = BitVector32.CreateSection(0xf, sectionB);
BitVector32.Section sectionD = BitVector32.CreateSection(0x7, sectionC);
BitVector32.Section sectionE = BitVector32.CreateSection(0x7, sectionD);
BitVector32.Section sectionF = BitVector32.CreateSection(0x3, sectionE);
Console.WriteLine($"Section A: {bits2[sectionA].ToBinaryString()}");
Console.WriteLine($"Section B: {bits2[sectionB].ToBinaryString()}");
Console.WriteLine($"Section C: {bits2[sectionC].ToBinaryString()}");
Console.WriteLine($"Section D: {bits2[sectionD].ToBinaryString()}");
Console.WriteLine($"Section E: {bits2[sectionE].ToBinaryString()}");
Console.WriteLine($"Section F: {bits2[sectionF].ToBinaryString()}");
Console.ReadLine();
}
}
可觀察的集合
如果需要集合中的元素何時刪除或添加的信息,就可以使用ObservableCollectionO類。這個類最初是為
WPF定義的,這樣UI就可以得知集合的變化,通用Windows應用程序使用它的方式相同。這個類的名稱空間 是System.Collections. ObjectModeloObservableCollection類派生自Collection基類,該基類可用于創建自定義集合,并在內部使用Ust 類。重寫基類中的虛方法SetltonO和RemoveltonO*以觸發CollectionChanged事件。這個類的用戶可以使用 INotifyCollectionChanged 接口注冊這個事件。
class Program
{
static void Main()
{
var data = new ObservableCollection<string>();
data.CollectionChanged += Data_CollectionChanged;
data.Add("One");
data.Add("Two");
data.Insert(1, "Three");
data.Remove("One");
data.CollectionChanged -= Data_CollectionChanged;
Console.ReadLine();
}
public static void Data_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
Console.WriteLine($"action: {e.Action.ToString()}");
if (e.OldItems != null)
{
Console.WriteLine($"starting index for old item(s): {e.OldStartingIndex}");
Console.WriteLine("old item(s):");
foreach (var item in e.OldItems)
{
Console.WriteLine(item);
}
}
if (e.NewItems != null)
{
Console.WriteLine($"starting index for new item(s): {e.NewStartingIndex}");
Console.WriteLine("new item(s): ");
foreach (var item in e.NewItems)
{
Console.WriteLine(item);
}
}
Console.WriteLine();
}
}
不變的集合
如果對象可以改變其狀態,就很難在多個同時運行的任務中使用。這些集合必須同步。如果對象不能改變 其狀態,就很容易在多個線程中使用。不能改變的對象稱為不變的對象。不能改變的集合稱為不變的集合。
public class Account
{
public Account(string name, decimal amount)
{
Name = name;
Amount = amount;
}
public string Name { get; }
public decimal Amount { get; }
}
class Program
{
static void Main()
{
SimpleArrayDemo();
ImmutableList<Account> accounts = CreateImmutableList();
UsingABuilder(accounts);
LinqDemo();
Console.ReadLine();
}
public static void LinqDemo()
{
ImmutableArray<string> arr = ImmutableArray.Create<string>("one", "two", "three", "four", "five");
var result = arr.Where(s => s.StartsWith("t"));
}
public static void UsingABuilder(ImmutableList<Account> immutableAccounts)
{
ImmutableList<Account>.Builder builder = immutableAccounts.ToBuilder();
for (int i = 0; i < builder.Count; i++)
{
Account a = builder[i];
if (a.Amount > 0)
{
builder.Remove(a);
}
}
ImmutableList<Account> overdrawnAccounts = builder.ToImmutable();
overdrawnAccounts.ForEach(a => Console.WriteLine($"{a.Name} {a.Amount}"));
}
public static ImmutableList<Account> CreateImmutableList()
{
var accounts = new List<Account>() {
new Account("Scrooge McDuck", 667377678765m),
new Account("Donald Duck", -200m),
new Account("Ludwig von Drake", 20000m)
};
ImmutableList<Account> immutableAccounts = accounts.ToImmutableList();
foreach (var account in immutableAccounts)
{
Console.WriteLine($"{account.Name} {account.Amount}");
}
immutableAccounts.ForEach(a => Console.WriteLine($"{a.Name} {a.Amount}"));
return immutableAccounts;
}
public static void SimpleArrayDemo()
{
ImmutableArray<string> a1 = ImmutableArray.Create<string>();
ImmutableArray<string> a2 = a1.Add("Williams");
ImmutableArray<string> a3 =
a2.Add("Ferrari").Add("Mercedes").Add("Red Bull Racing");
}
}
并發集合
不變的集合很容易在多個線程中使用,因為它們不能改變。如果希望使用應在多個線程中改變的集合,.NET 在名稱空間System.Collections.Concurrent中提供了幾個線程安全的集合類。線程安全的集合可防止多個線程以 相互沖突的方式訪問集合。
為了對集合進行線程安全的訪問,定義了 IProducerConsumerCollection接口。這個接口中最重要的方法是 TryAdd()和TryTake()。TryAdd()方法嘗試給集合添加一項,但如果集合禁止添加項,這個操作就可能失敗。為了給 出相關信息,TiyAdd()方法返回一個布爾值,以說明操作是成功還是失敗。TryTake()方法也以這種方式工作,以通 知調用者操作是成功還是失敗,并在操作成功時返回集合中的項。
public class ColoredConsole
{
private static object syncOutput = new object();
public static void WriteLine(string message)
{
lock (syncOutput)
{
Console.WriteLine(message);
}
}
public static void WriteLine(string message, string color)
{
lock (syncOutput)
{
Console.ForegroundColor = (ConsoleColor)Enum.Parse(
typeof(ConsoleColor), color);
Console.WriteLine(message);
Console.ResetColor();
}
}
}
public class Info
{
public Info(string word, int count)
{
Word = word;
Count = count;
}
public string Word { get; }
public int Count { get; }
public string Color { get; set; }
public override string ToString() => $"{Count} times: {Word}";
}
public static class PipelineStages
{
public static Task ReadFilenamesAsync(string path, BlockingCollection<string> output)
{
return Task.Factory.StartNew(() =>
{
foreach (string filename in Directory.EnumerateFiles(path, "*.cs",
SearchOption.AllDirectories))
{
output.Add(filename);
ColoredConsole.WriteLine($"stage 1: added {filename}");
}
output.CompleteAdding();
}, TaskCreationOptions.LongRunning);
}
public static async Task LoadContentAsync(BlockingCollection<string> input, BlockingCollection<string> output)
{
foreach (var filename in input.GetConsumingEnumerable())
{
using (FileStream stream = File.OpenRead(filename))
{
var reader = new StreamReader(stream);
string line = null;
while ((line = await reader.ReadLineAsync()) != null)
{
output.Add(line);
ColoredConsole.WriteLine($"stage 2: added {line}");
await Task.Delay(20);
}
}
}
output.CompleteAdding();
}
public static Task ProcessContentAsync(BlockingCollection<string> input, ConcurrentDictionary<string, int> output)
{
return Task.Factory.StartNew(() =>
{
foreach (var line in input.GetConsumingEnumerable())
{
string[] words = line.Split(' ', ';', '\t', '{', '}', '(', ')',
':', ',', '"');
foreach (var word in words.Where(w => !string.IsNullOrEmpty(w)))
{
output.AddOrUpdate(key: word, addValue: 1, updateValueFactory: (s, i) => ++i);
ColoredConsole.WriteLine($"stage 3: added {word}");
}
}
}, TaskCreationOptions.LongRunning);
}
public static Task TransferContentAsync(ConcurrentDictionary<string, int> input, BlockingCollection<Info> output)
{
return Task.Factory.StartNew(() =>
{
foreach (var word in input.Keys)
{
if (input.TryGetValue(word, out int value))
{
var info = new Info(word, value);
output.Add(info);
ColoredConsole.WriteLine($"stage 4: added {info}");
}
}
output.CompleteAdding();
}, TaskCreationOptions.LongRunning);
}
public static Task AddColorAsync(BlockingCollection<Info> input, BlockingCollection<Info> output)
{
return Task.Factory.StartNew(() =>
{
foreach (var item in input.GetConsumingEnumerable())
{
if (item.Count > 40)
{
item.Color = "Red";
}
else if (item.Count > 20)
{
item.Color = "Yellow";
}
else
{
item.Color = "Green";
}
output.Add(item);
ColoredConsole.WriteLine($"stage 5: added color {item.Color} to {item}");
}
output.CompleteAdding();
}, TaskCreationOptions.LongRunning);
}
public static Task ShowContentAsync(BlockingCollection<Info> input)
{
return Task.Factory.StartNew(() =>
{
foreach (var item in input.GetConsumingEnumerable())
{
ColoredConsole.WriteLine($"stage 6: {item}", item.Color);
}
}, TaskCreationOptions.LongRunning);
}
}
class Program
{
static void Main()
{
StartPipelineAsync().Wait();
Console.ReadLine();
}
public static async Task StartPipelineAsync()
{
var fileNames = new BlockingCollection<string>();
var lines = new BlockingCollection<string>();
var words = new ConcurrentDictionary<string, int>();
var items = new BlockingCollection<Info>();
var coloredItems = new BlockingCollection<Info>();
Task t1 = PipelineStages.ReadFilenamesAsync(@"../..", fileNames);
ColoredConsole.WriteLine("started stage 1");
Task t2 = PipelineStages.LoadContentAsync(fileNames, lines);
ColoredConsole.WriteLine("started stage 2");
Task t3 = PipelineStages.ProcessContentAsync(lines, words);
await Task.WhenAll(t1, t2, t3);
ColoredConsole.WriteLine("stages 1, 2, 3 completed");
Task t4 = PipelineStages.TransferContentAsync(words, items);
Task t5 = PipelineStages.AddColorAsync(items, coloredItems);
Task t6 = PipelineStages.ShowContentAsync(coloredItems);
ColoredConsole.WriteLine("stages 4, 5, 6 started");
await Task.WhenAll(t4, t5, t6);
ColoredConsole.WriteLine("all stages finished");
}
}
原文鏈接:https://blog.csdn.net/huan13479195089/article/details/127033890
相關推薦
- 2022-11-15 SQL?Server?ISNULL?不生效原因及解決_MsSql
- 2022-04-09 SpringBoot上傳文件并配置本地資源映射來訪問文件
- 2023-01-17 MATLAB算法技巧和實現斐波那契數列的解決思路_C 語言
- 2022-11-19 Python?numpy?ndarray屬性,索引,切片_python
- 2022-02-28 react高階函數和函數柯里化 學習
- 2022-11-14 React中的生命周期詳解_React
- 2022-10-23 C/C++指針介紹與使用詳解_C 語言
- 2022-02-23 IDEA git 拉取項目時報 No tracked branch configured for b
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支