1. Dictionary
和java中的Map類似,可以用來存放鍵值對。
說明
必須包含名空間System.Collection.Generic
Dictionary里面的每一個元素都是一個鍵值對(由二個元素組成:鍵和值)
鍵必須是唯一的,而值不需要唯一的
鍵和值都可以是任何類型(比如:string, int, 自定義類型,等等)
通過一個鍵讀取一個值的時間是接近O(1)
鍵值對之間的偏序可以不定義
-
創建及初始化
Dictionary<int,string>myDictionary=newDictionary<int,string>();
-
添加元素
myDictionary.Add(1,"C#");
myDictionary.Add(2,"C++");
myDictionary.Add(3,"ASP.NET");
myDictionary.Add(4,"MVC");
-
通過Key查找元素
if(myDictionary.ContainsKey(1))
{
Console.WriteLine("Key:{0},Value:{1}","1", myDictionary[1]);
}
-
通過KeyValuePair遍歷元素
foreach(KeyValuePair<int,string>kvp in myDictionary)
...{
Console.WriteLine("Key = {0}, Value = {1}",kvp.Key, kvp.Value);
}
-
僅遍歷鍵 Keys 屬性
Dictionary<int,string>.KeyCollection keyCol=myDictionary.Keys;
foreach(intkeyinkeyCol)
...{
Console.WriteLine("Key = {0}", key);
}
-
僅遍歷值 Valus屬性
Dictionary<int,string>.ValueCollection valueCol=myDictionary.Values;
foreach(stringvalueinvalueCol)
...{
Console.WriteLine("Value = {0}", value);
}
-
通過Remove方法移除指定的鍵值
myDictionary.Remove(1);
if(myDictionary.ContainsKey(1))
...{
Console.WriteLine("Key:{0},Value:{1}","1", myDictionary[1]);
}
else
{
Console.WriteLine("不存在 Key : 1");
}
下面是我自己的例子:
2. 正則表達式/HTML圖片顯示/Select下拉框
2.1 正則表達式
正則表達式,又稱規則表達式,英文名為Regular Expression,在代碼中常簡寫為regex、regexp或RE,是計算機科學的一個概念。正則表通常被用來檢索、替換那些符合某個模式(規則)的文本。
正則表達式是對字符串(包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為“元字符”))操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字符串”,這個“規則字符串”用來表達對字符串的一種過濾邏輯。正則表達式是一種文本模式,模式描述在搜索文本時要匹配的一個或多個字符串。
上圖為控制輸入框的內容不能為漢字的正則表達式。每個符號所代表的意思如下:
2.2 HTML圖片顯示
在使用<img>標簽顯示圖片時,如果圖片太大顯示會超出div的大小。這回導致頁面可以橫向滑動,但是沒有圖片的地方div大小正常,被圖片撐大的部分顯示的就是上一個頁面的內容。
水平方向撐開的解決方法就是添加style=”display:block;width:100%。其中,display:block;此元素將顯示為塊級元素,此元素前后會帶有換行符。width:100%,將寬度設為100%,這個塊級元素寬度就被固定了。該元素不會被撐開,而是按比例縮小顯示。
如果加入圖片較小能在一個頁面顯示可以按照水平方向的解決方法加上height:100%解決,但是如果圖片較大,需要下拉。可以在頁面加一個滾動條style="overflow-y: scroll;"原本未加滾動條時,因為圖片大將<img>元素撐大,不在所框住的div內,也能下拉,但是能看到上一頁面的未覆蓋的內容。加了y方向的滾動條后就能解決這一問題。
2.3 Select下拉框
在 HTML 表單中,<select> 標簽每出現一次,一個 Select 對象就會被創建。在使用選擇框時,如需要默認初始值,添加selected = 'selected'; 屬性,該選項即為默認選項。
將初始val賦為空,這樣“請選擇”項的val即為空,世紀選項就沒有“請選擇”項了。
源碼:
<input type="text" class="uc-a1" style="border: none;font-size:
0.8125em;"id="RelaCredNo"onkeyup="value=value.replace(/[^\w\.\/]/ig,'')">
<div class="bc-bg" tabindex="0" data-control="PAGE" id="Page" style="overflow-y: scroll">
$("#show_img").append('<img src="'+relaImage+'" style="display:block;width:100%">');
var result = JSON.parse(appcan.locStorage.getVal("selectRelaType"));
var str = "";
str += "<option value='' selected = 'selected'>請選擇</option>";
if (result.indexOf("本人|") < 0) {
str += "<option value='1'>本人</option>";
}
if (result.indexOf("父親|") < 0) {
str += "<option value='2'>父親</option>";
}
if (result.indexOf("母親|") < 0) {
str += "<option value='3'>母親</option>";
}
if (result.indexOf("配偶父|") < 0) {
str += "<option value='4'>配偶父</option>";
}
if (result.indexOf("配偶母|") < 0) {
str += "<option value='5'>配偶母</option>";
}
if (result.indexOf("配偶|") < 0) {
str += "<option value='6'>配偶</option>";
}
str += "<option value='7'>子女</option>";
$("#RelaType").append(str);
$('#RelaType').val("");
$("#RelaCredType").append("<option value='' selected = 'selected'>請選擇</option>
<option value='1'>身份證</option><option value='2'>護照</option>");
$('#RelaCredType').val("");
3. 容器介紹
3.1 Array/ArrayList/List/LinkedList
-
Array
數組在C#中最早出現的。在內存中是連續存儲的,所以它的索引速度非常快,而且賦值與修改元素也很簡單。
1. string[] s=new string[2];
2.
3. //賦值
4. s[0]="a";
5. s[1]="b";
6. //修改
7. s[1]="a1";
但是數組存在一些不足的地方。在數組的兩個數據間插入數據是很麻煩的,而且在聲明數組的時候必須指定數組的長度,數組的長度過長,會造成內存浪費,過短會造成數據溢出的錯誤。如果在聲明數組時我們不清楚數組的長度,就會變得很麻煩。
針對數組的這些缺點,C#中最先提供了ArrayList對象來克服這些缺點。
底層數據結構就是數組。
-
ArrayList
ArrayList是命名空間System.Collections下的一部分,在使用該類時必須進行引用,同時繼承了IList接口,提供了數據存儲和檢索。ArrayList對象的大小是按照其中存儲的數據來動態擴充與收縮的。所以,在聲明ArrayList對象時并不需要指定它的長度。
1. ArrayList list1 = new ArrayList();
2.
3. //新增數據
4. list1.Add("cde");
5. list1.Add(5678);
6.
7. //修改數據
8. list[2] = 34;
9.
10. //移除數據
11. list.RemoveAt(0);
12.
13. //插入數據
14. list.Insert(0, "qwe");
從上面例子看,ArrayList好像是解決了數組中所有的缺點,為什么又會有List?
我們從上面的例子看,在List中,我們不僅插入了字符串cde,而且插入了數字5678。這樣在ArrayList中插入不同類型的數據是允許的。因為ArrayList會把所有插入其中的數據當作為object類型來處理,在我們使用ArrayList處理數據時,很可能會報類型不匹配的錯誤,也就是ArrayList不是類型安全的。在存儲或檢索值類型時通常發生裝箱和取消裝箱操作,帶來很大的性能耗損。
裝箱與拆箱的概念:
裝箱:就是將值類型的數據打包到引用類型的實例中比如將string類型的值abc賦給object對象obj
1. String i=”abc”;
2. object obj=(object)i;
拆箱:就是從引用數據中提取值類型
比如將object對象obj的值賦給string類型的變量i。
1. object obj=”abc”;
2. string i=(string)obj;
裝箱與拆箱的過程是很損耗性能的。
底層數據結構就是數組。類似于C++里面沒有泛型的Vector。
-
泛型List
因為ArrayList存在不安全類型與裝箱拆箱的缺點,所以出現了泛型的概念。List類是ArrayList類的泛型等效類,它的大部分用法都與ArrayList相似,因為List類也繼承了IList接口。最關鍵的區別在于,在聲明List集合時,我們同時需要為其聲明List集合內數據的對象類型。
比如:
1. List<string> list = new List<string>();
2. //新增數據
3. list.Add(“abc”);
4. //修改數據
5. list[0] = “def”;
6. //移除數據
7. list.RemoveAt(0);
上例中,如果我們往List集合中插入int數組123,IDE就會報錯,且不能通過編譯。這樣就避免了前面講的類型安全問題與裝箱拆箱的性能問題了。
底層數據結構就是數組。類似于C++里面的Vector。
-
LinkedList
用雙鏈表實現的List,特點是插入刪除快,查找慢
LinkedList<T> 提供 LinkedListNode<T> 類型的單獨節點,因此插入和移除的運算復雜度為 O(1)。
可以移除節點,然后在同一列表或其他列表中重新插入它們,這樣在堆中便不會分配額外的對象。由于該列表還維護內部計數,因此獲取 Count 屬性的運算復雜度為 O(1)。
LinkedList<T> 對象中的每個節點都屬于 LinkedListNode<T> 類型。由于 LinkedList<T> 是雙向鏈表,因此每個節點向前指向 Next 節點,向后指向 Previous 節點。
1. LinkedList<string> list = new LinkedList<string>();
2. list.AddFirst("Data Value 1");
3. list.AddLast("Data Value 6");
關于List和LonkedList的一個性能比較
-
增加 刪除
在List<T>中增加、刪除節點的速度,大體上快于使用LinkedList<T>時的相同操作。將 List<T>.Add方法和LinkedList<T>的Add*方法相比較,真正的性能差別不在于Add操作,而在LinkedList<T>在給GC(垃圾回收機制)的壓力上。一個List<T>本質上是將其數據保存在一個堆棧的數組上,而LinkedList<T>是將其所有節點保存在堆棧上(人家是一個,我是一系列)。這就使得GC需要更多地管理堆棧上LinkedList<T>的節點對象。注意,List<T>.Insert方法比在LinkedList<T>中使用Add方法在任何地方添加一個節點可能要慢。然而,這個依賴于List<T>插入對象的位置。Insert方法必須使所有在插入點后面的元素往后移動一位。如果新元素被插在List<T>最后或接近最后的位置,那么相對于GC維護LinkedList<T>節點的總的開銷來說,其開銷是可以被忽略的。
-
索引
另一個List<T>性能優于LinkedList<T>的地方是你在使用索引進行訪問的時候。在List<T>中,你可以使用索引值(indexer)直接定位到某個具體的元素位置。而在LinkedList<T>中,卻沒有這樣的奢侈品。在LinkedList<T>中,你必須通過Previous或Next屬性遍歷整個List,直到找到你想要的節點。
3.2 HashSet/HashTable/Dictionary
這三個容器的底層都是Hash表。
-
HashSet
MSDN很簡單的解釋:表示值的集。
HashSet<T> 類提供了高性能的集運算。一組是一個集合,不包含任何重復的元素,且的元素順序不分先后。
用了hash table來儲存數據,是為了用O(n)的space來換取O(n)的時間,也就是查找元素的時間是O(1)。
它包含一些集合的運算
HashSet<T> 提供了許多數學設置操作例如,組添加 (聯合),并設置減法。下表列出了所提供 HashSet<T> 操作和及其數學等效項。
UnionWith - Union 或將其設置的添加
IntersectWith - 交集
ExceptWith - Set 減法
SymmetricExceptWith - 余集
列出的集操作中,除了 HashSet<T> 類還提供了方法來確定 set 是否相等、 重疊的集,以及一組是否為子集或另一個集的超集。
example
1. HashSet<int> evenNumbers = new HashSet<int>();
2. HashSet<int> oddNumbers = new HashSet<int>();
3.
4. for (int i = 0; i < 5; i++)
5. {
6. // Populate numbers with just even numbers.
7. evenNumbers.Add(i * 2);
8. // Populate oddNumbers with just odd numbers.
9. oddNumbers.Add((i * 2) + 1);
10. }
11. // Create a new HashSet populated with even numbers.
12. HashSet<int> numbers = new HashSet<int>(evenNumbers);
13. numbers.UnionWith(oddNumbers);
-
HashTable
表示根據鍵的哈希代碼進行組織的鍵/值對的集合。
Hashtable是System.Collections命名空間提供的一個容器,用于處理和表現類似key/value的鍵值對,其中key通常可用來快速查找,同時key是區分大小寫;value用于存儲對應于key的值。
Hashtable中key/value鍵值對均為object類型,所以Hashtable可以支持任何類型的key/value鍵值對.
他內部維護很多對Key-Value鍵值對,其還有一個類似索引的值叫做散列值(HashCode),它是根據GetHashCode方法對Key通過一定算法獲取得到的,所有的查找操作定位操作都是基于散列值來實現找到對應的Key和Value值的
當前HashTable中的被占用空間達到一個百分比的時候就將該空間自動擴容,在.net中這個百分比是72%,也叫.net中HashTable的填充因子為0.72。例如有一個HashTable的空間大小是100,當它需要添加第73個值的時候將會擴容此HashTable.
這個自動擴容的大小是多少呢?答案是當前空間大小的兩倍最接近的素數,例如當前HashTable所占空間為素數71,如果擴容,則擴容大小為素數131.
1. Hashtable openWith = new Hashtable();
2.
3. // Add some elements to the hash table. There are no
4. // duplicate keys, but some of the values are duplicates.
5. openWith.Add("txt", "notepad.exe");
6. openWith.Add("bmp", "paint.exe");
7. openWith.Add("dib", "paint.exe");
8. openWith.Add("rtf", "wordpad.exe");
HashTable也有Boxing和Unboxing的開銷。
然后就有了
-
Dictionary
Dictionary也是鍵值容器,存入對象是需要與[key]值一一對應的存入該泛型。相對于HashTable,類似于List和ArrayList的關系。它是類型安全的。
1. Dictionary<string, string> myDic = new Dictionary<string, string>();
2. myDic.Add("aaa", "111");
3. myDic.Add("bbb", "222");
4. myDic.Add("ccc", "333");
5. myDic.Add("ddd", "444");
-
小結
數組的容量是固定的,您只能一次獲取或設置一個元素的值,而ArrayList或List<T>的容量可根據需要自動擴充、修改、刪除或插入數據。
數組可以具有多個維度,而 ArrayList或 List< T> 始終只具有一個維度。但是,您可以輕松創建數組列表或列表的列表。特定類型(Object 除外)的數組 的性能優于 ArrayList的性能。 這是因為 ArrayList的元素屬于 Object 類型;所以在存儲或檢索值類型時通常發生裝箱和取消裝箱操作。不過,在不需要重新分配時(即最初的容量十分接近列表的最大容量),List< T> 的性能與同類型的數組十分相近。
在決定使用 List<T> 還是使用ArrayList 類(兩者具有類似的功能)時,記住List<T> 類在大多數情況下執行得更好并且是類型安全的。如果對List< T> 類的類型T 使用引用類型,則兩個類的行為是完全相同的。但是,如果對類型T使用值類型,則需要考慮實現和裝箱問題。
所以基本不怎么用ArrayList.
還要注意的一點
在單線程的時候使用Dictionary更好一些,多線程的時候使用HashTable更好。
因為HashTable可以通過Hashtable tab = Hashtable.Synchronized(new Hashtable());獲得線程安全的對象。
網上找的C#學習內容:
HTML---css/div---- SQL----C#----面向對象-----設計模式----MVC----EntityFramework-----C#深入了解-----WebForm-----javascript----jquery----angularJS----.netCore------現在。。。。
往后我可能要繼續學習-----架構----深入理解設計模式------.netCore-----NodeJs.------Git-----Docker
還有Unity3D------操作系統-----編譯原理-----數據結構等。。。。。。。
4. Python多線程與多線程中join()的用法
Python多線程與多進程中join()方法的效果是相同的。
下面僅以多線程為例:
首先需要明確幾個概念:
知識點一:
當一個進程啟動之后,會默認產生一個主線程,因為線程是程序執行流的最小單元,當設置多線程時,主線程會創建多個子線程,在python中,默認情況下(其實就是setDaemon(False)),主線程執行完自己的任務以后,就退出了,此時子線程會繼續執行自己的任務,直到自己的任務結束,例子見下面一。知識點二:
當我們使用setDaemon(True)方法,設置子線程為守護線程時,主線程一旦執行結束,則全部線程全部被終止執行,可能出現的情況就是,子線程的任務還沒有完全執行結束,就被迫停止,例子見下面二。知識點三:
此時join的作用就凸顯出來了,join所完成的工作就是線程同步,即主線程任務結束之后,進入阻塞狀態,一直等待其他的子線程執行結束之后,主線程在終止,例子見下面三。知識點四:
join有一個timeout參數:
- 當設置守護線程時,含義是主線程對于子線程等待timeout的時間將會殺死該子線程,最后退出程序。所以說,如果有10個子線程,全部的等待時間就是每個timeout的累加和。簡單的來說,就是給每個子線程一個timeout的時間,讓他去執行,時間一到,不管任務有沒有完成,直接殺死。
- 沒有設置守護線程時,主線程將會等待timeout的累加和這樣的一段時間,時間一到,主線程結束,但是并沒有殺死子線程,子線程依然可以繼續執行,直到子線程全部結束,程序退出。
4.1 Python多線程的默認情況
import threading
import time
def run():
time.sleep(2)
print('當前線程的名字是: ', threading.current_thread().name)
time.sleep(2)
if __name__ == '__main__':
start_time = time.time()
print('這是主線程:', threading.current_thread().name)
thread_list = []
for i in range(5):
t = threading.Thread(target=run)
thread_list.append(t)
for t in thread_list:
t.start()
print('主線程結束!' , threading.current_thread().name)
print('一共用時:', time.time()-start_time)
其執行結果如下
C:\Users\yuanyizhang\AppData\Local\Programs\Python\Python36-32\python.exe
C:/Users/yuanyizhang/PycharmProjects/untitled/test.py
這是主線程: MainThread
主線程結束! MainThread
一共用時: 0.0020051002502441406
當前線程的名字是: Thread-1
當前線程的名字是: Thread-5
當前線程的名字是: Thread-4
當前線程的名字是: Thread-3
當前線程的名字是: Thread-2
Process finished with exit code 0
關鍵點:
- 我們的計時是對主線程計時,主線程結束,計時隨之結束,打印出主線程的用時。
- 主線程的任務完成之后,主線程隨之結束,子線程繼續執行自己的任務,直到全部的子線程的任務全部結束,程序結束。
4.2 設置守護線程
import threading
import time
def run():
time.sleep(2)
print('當前線程的名字是: ', threading.current_thread().name)
time.sleep(2)
if __name__ == '__main__':
start_time = time.time()
print('這是主線程:', threading.current_thread().name)
thread_list = []
for i in range(5):
t = threading.Thread(target=run)
thread_list.append(t)
for t in thread_list:
t.setDaemon(True)
t.start()
print('主線程結束了!' , threading.current_thread().name)
print('一共用時:', time.time()-start_time)
其執行結果如下,注意請確保setDaemon()在start()之前。
C:\Users\yuanyizhang\AppData\Local\Programs\Python\Python36-32\python.exe
C:/Users/yuanyizhang/PycharmProjects/untitled/test.py
這是主線程: MainThread
主線程結束了! MainThread
一共用時: 0.0010030269622802734
Process finished with exit code 0
關鍵點:
- 非常明顯的看到,主線程結束以后,子線程還沒有來得及執行,整個程序就退出了。
4.3 join的作用
import threading
import time
def run():
time.sleep(2)
print('當前線程的名字是: ', threading.current_thread().name)
time.sleep(2)
if __name__ == '__main__':
start_time = time.time()
print('這是主線程:', threading.current_thread().name)
thread_list = []
for i in range(5):
t = threading.Thread(target=run)
thread_list.append(t)
for t in thread_list:
t.setDaemon(True)
t.start()
for t in thread_list:
t.join()
print('主線程結束了!' , threading.current_thread().name)
print('一共用時:', time.time()-start_time)
其執行結果如下:
這是主線程: MainThread
當前線程的名字是: Thread-1
當前線程的名字是: Thread-2
當前線程的名字是: Thread-4
當前線程的名字是: Thread-5
當前線程的名字是: Thread-3
主線程結束了! MainThread
一共用時: 4.004054546356201
關鍵點:
- 可以看到,主線程一直等待全部的子線程結束之后,主線程自身才結束,程序退出。
- 可以通過join(time)設置時間 控制主線程是否等待子線程結束再結束,設置時間較小時,等待時間不足,主線程會先結束(本例可設置join(0.3)),時間足夠長時,主線程等待足夠時間,子線程可以全部結束(本例設置join(1))
5. Flex布局
flex 做布局太容易了,尤其是在垂直居中這方面
布局的傳統解決方案,基于盒狀模型,依賴 display 屬性 + position屬性 + float屬性。它對于那些特殊布局非常不方便,比如,垂直居中就不容易實現。
Flex 是 Flexible Box 的縮寫,意為"彈性布局",用來為盒狀模型提供最大的靈活性。
任何一個容器都可以指定為 Flex 布局。
.box{
display: flex;
}
行內元素也可以使用 Flex 布局。
.box{
display: inline-flex;
}
Webkit 內核的瀏覽器,必須加上-webkit前綴。
注意,設為 Flex 布局以后,子元素的float、clear和vertical-align屬性將失效。
容器默認存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫做main start,結束位置叫做main end;交叉軸的開始位置叫做cross start,結束位置叫做cross end。
項目默認沿主軸排列。單個項目占據的主軸空間叫做main size,占據的交叉軸空間叫做cross size。
容器的屬性
以下6個屬性設置在容器上。
flex-direction
flex-wrap
flex-flow
justify-content
align-items
具體各個屬性值與作用參考
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html