JAVA集合LIST MAP SET详解
1. 集合框架介绍
我们知道,计算机的优势在于处理大量的数据,在编程开发中,为处理大量的数据,必须具备相应的存储结构,之前学习的数组可以用来存储并处理大量类型相同的数据,但是通过上面的课后练习,会发现数组在应用中的限制:数组长度一旦确定,就无法更改;除非采用建立新数组,再将原数组内容拷贝过来;数组中只能存放指定类型的数据,操作不方便。在实际开发中,为了操作方便,JDK中提供了List集合。
List集合与数组的用途非常相似,都是用来存储大量数据的,不同处有两点:
1. 数组长度在使用前必须确定,一旦确定不能改变。而List集合长度可变,无需定义。
2. 数组中必须存放同一类型的数据,List集合中可以存放不同类型的数据。
List集合是Java集合框架中的一种,另外两种集合Set和Map会在下面介绍。List集合在JDK中被封装称为接口,针对List接口,有若干种实现,常用的有三个子类,即ArrayList、Vector和LinkedList。这三个类的功能与用法相同,但内部实现方式不同。下面以ArrayList为例介绍集合的常用操作,Vector和LinkedList的使用方法与ArrayList类似。
数组与List集合的常规操作类似,下面通过代码对比两者的用法:
代码演示:数组的基本操作
public class ArrayDemo { public static void main(String[] args) { String[] array = new String[3]; for (int i = 0; i < 3; i++) { array[i] = "Hello"; } String a = array[0]; } } |
代码演示:List集合的基本操作
import java.util.ArrayList; ① public class ListDemo { public static void main(String[] args) { ArrayList list = new ArrayList(); ② for (int i = 0; i < 3; i++) { list.add("Hello"); ③ } String a = (String)list.get(0); ④ } } |
代码解析:
① 集合框架在java.util包中,使用前必须使用import语句引入对应的类。
② List集合的定义时不需要指定大小,也不用指定集合中保存的数据类型。
③ 向List集合中添加数据时不需要制定下标,List集合会自动生成下标。
④ 获取List集合的元素时使用get方法并传入下标,然后强制类型转换为实际类型。
代码演示:使用集合记录学员姓名
public static void main(String[] args) { System.out.println("请输入班级学员姓名,输入OVER结束"); java.util.Scanner scanner = new java.util.Scanner(System.in); ArrayList list = new ArrayList(); do { String name = scanner.next(); if (name.equalsIgnoreCase("OVER")) break; list.add(name); } while (true); System.out.println(list); ① } |
代码解析:
① List集合重写了toString方法,可以将集合中的元素依次输出。
2. List集合的常用方法
下表列出了List集合的常用方法:
返回类型 |
方法名称 |
说明 |
boolean |
add(Object obj) |
加入元素,返回是否添加成功 |
boolean |
clear() |
清除集合中的元素 |
boolean |
contains(Object obj) |
查找集合中是否存在传入的元素 |
Object |
get(int index) |
获取指定位置的元素 |
boolean |
isEmpty() |
判断集合是否为空 |
Object |
remove(int index) |
删除制定位置的元素,并返回该元素 |
int |
size() |
获取集合大小 |
Object[] |
toArray() |
将集合转换成一个数组 |
表: List集合的常用方法
下面通过实例演示各个方法的用途:
代码演示:List集合的常用方法
import java.util.ArrayList; public class Demo { public static java.util.Scanner scanner = new java.util.Scanner(System.in); public static void main(String[] args) { ArrayList listA = new ArrayList(); ArrayList listB = new ArrayList(); System.out.println("请输入A班学员姓名,输入OVER结束"); inputName(listA); System.out.println("请输入B班学员姓名,输入OVER结束"); inputName(listB); //合并集合listA与listB listA.addAll(listB); System.out.println("请输入要查找的学员姓名"); String name = scanner.next(); int pos = listA.indexOf(name); if (pos==-1) { System.out.println("没有找到"); } else { System.out.println("找到了,位置是:" + pos); } System.out.println("请输入要删除的学员姓名"); String delName = scanner.next(); if (listA.remove(delName)) { System.out.println("删除成功!"); } else { System.out.println("没有该学员"); } } public static void inputName(ArrayList list) { do { String name = scanner.next(); if (name.equalsIgnoreCase("OVER")) break; list.add(name); } while (true); } } |
3. 使用List集合保存对象
使用List集合保存对象时,主要注意以下几点:
1. 集合中保存的是对象的引用,观察以下代码:
代码演示:使用集合保存对象
import java.util.ArrayList; class Student { String name; int age; public Student(String name, int age) { this.name = name; this.age = age; } public String toString() { return name + "/" + age; } } public class Demo { public static void main(String[] args) { ArrayList list = new ArrayList(); Student stu = new Student("Tom" , 10); for (int i = 0; i < 3; i++) { stu.age = 10 + i; list.add(stu); } System.out.println(list); } } |
上面代码的原意是在集合中保存三个Student对象,age分别为10、11、12,但实际输出的age值均为12。这是因为list集合中保存的是stu对象的引用,而在循环中stu的引用并没有变化,所以循环结束后集合中的三个元素都指向stu对象,age的值自然也是最后的12。将代码“Student stu = new Student("Tom" , 10);”放入循环内可以解决这一问题。
2. 使用remove、contains、indexOf等方法时,应该重写类的equals方法,观察以下代码:
代码演示:未重写equals方法的代码
//省略了Student类的定义 public class Demo { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(new Student("Tom" , 11)); list.add(new Student("Jerry" , 22)); list.add(new Student("Alice" , 33)); System.out.println(list.contains(new Student("Tom" , 11))); System.out.println(list.indexOf(new Student("Jerry" , 22))); System.out.println(list.remove(new Student("Alice" , 33))?"成功":"无此项"); } } |
在上例中,我们希望判断学员Tom是否存在,查找学员Jerry,删除学员Alice,但是输出的结果却是不存在,找不到,删不掉。这是因为List集合会调用元素的equals方法来判断对象是否相等,而Student类没有重写equals方法,默认是按引用地址比较,而每个学员对象的地址又不相同,所以出现这个现象。通过给Student类添加equals方法可以解决这个问题:
代码演示:重写equals方法后的Student类
class Student { String name; int age; public Student(String name, int age) { this.name = name; this.age = age; } public boolean equals(Object obj) { if (obj == null) return false; if (!(obj instanceof Student)) return false; Student stu = (Student) obj; return stu.name.equals(this.name) && stu.age == this.age; } } |
4. 三种List集合的比较
我们说过,ArrayList、Vector与LinkedList的使用方法相同,内部实现方式不同。而内部实现方式的不同又决定了三种集合的适用范围,了解三种集合的内部实现,才能正确的选择使用类型。
? ArrayList与Vector比较
ArrayList与Vector的内部实现类似,Vector设计为线程安全,ArrayList设计为非线程安全。为了保证线程安全,Vector在性能方面稍逊于ArrayList,目前我们编写的都是单线程应用程序,应选择使用ArrayList。
? ArrayList与LinkedList
ArrayList与LinkedList均设计为非线程安全,ArrayList内部采用数组实现(与Vector相同),LinkedList内部采用链表结构实现。
ArrayList采用数组保存元素,意味着当大量添加元素,数组空间不足时,依然需要通过新建数组、内存复制的方式来增加容量,效率较低;而当进行对数组进行插入、删除操作时,又会进行循环移位操作,效率也较低;只有进行按下标查询时(get方法),使用数组效率很高。
LinkedList采用链表保存元素,在添加元素时只需要进行一次简单的内存分配即可,效率较高;进行插入、删除操作时,只需对链表中相邻的元素进行修改即可,效率也很高;但进行按下标查询时,需要对链表进行遍历,效率较低。下图演示了链表结构的特性:
图: 链表结构,每个元素引用后面的元素
图: 向链表中插入元素,只需修改两处引用
图: 删除链表中的元素,也只需要修改两处引用
可以总结出ArrayList在进行数据的新增、插入、删除时效率较低,按下标对数据进行查找时效率较高;LinkedList正好相反。一般来说ArrayList保存经常进行查询操作的集合,LinkedList适用于保存经常进行修改操作的集合。
5. 章节概述
1. List集合与数组的区别。
2. List集合实际上包含了3个常用的集合类,即ArrayList、Vector和LinkedList。
3. List集合的常用操作。
4. ArrayList采用数组保存元素,意味着当大量添加元素,数组空间不足时,依然需要通过新建数组、内存复制的方式来增加容量,效率较低;而当进行对数组进行插入、删除操作时,又会进行循环移位操作,效率也较低;只有进行按下标查询时(get方法),使用数组效率很高。
5. ArrayList与Vector的内部实现类似,Vector设计为线程安全,ArrayList设计为非线程安全。为了保证线程安全,Vector在性能方面稍逊于ArrayList,目前我们编写的都是单线程应用程序,应选择使用ArrayList。
6. ArrayList与LinkedList均设计为非线程安全,ArrayList内部采用数组实现(与Vector相同),LinkedList内部采用链表结构实现。
7. LinkedList采用链表保存元素,在添加元素时只需要进行一次简单的内存分配即可,效率较高;进行插入、删除操作时,只需对链表中相邻的元素进行修改即可,效率也很高;但进行按下标查询时,需要对链表进行遍历,效率较低。
1. Map集合
在上面讲的List集合中,可用通过List集合提供的各种方法来对其中的元素进行操作,从而可以方便用户操作,但是如果要从List集合中获取一个特定的对象,操作是比较繁琐的。
在类Person中有cardId和name两个属性,分别代表编号和姓名,创建两个Person对象并存储到ArrayList集合中 ,如果要从集合中获取指定的对象,则必须要通过迭代整个集合来获得,如下所示:
代码演示:Person类
public class Person { String cardId; String name; public Person(String cardId, String name) { this.cardId = cardId; this.name = name; } } |
代码演示:从ArrayList中获取特定的对象
public class ArrayListTest { public static void main(String[] args) { Person personA = new Person("001", "Tom"); Person personB = new Person("002", "Jack"); ArrayList list = new ArrayList(); list.add(personA); list.add(personB); for (int i = 0; i < list.size(); i++) { Person person = (Person) list.get(i); if (person.cardId.equals("002")) { System.out.println(person.name); } } } } |
从上面的示例中,我们看到从list集合中获取一个对象的繁琐,有没有简单的方法呢?在JDK中专门提供了Map集合来存储上面这种一对一映射关系的对象。
Map集合用于保存具有映射关系的数据,即以键值对(key->value)的方式来存储数据。因此在Map集合内部有两个集合,一个集合用于保存Map中的key(键),一个集合用于保存Map中的value(值),其中key和value可以是任意数据类型数据。
图: Map集合
Map集合中的常用类有Hashtable和HashMap,两个类的功能和用法相似,下面以HashMap为例介绍Map集合的用法。
代码演示:Map集合使用
public class MapTest { public static void main(String[] args) { HashMap map = new HashMap(); ① map.put("001", "Tom"); ② map.put("002", "Jack"); String name = (String) map.get("002"); ③ System.out.println(name); } } |
代码解析:
① 创建HashMap对象。
② 利用HashMap中的put方法将键值对形式的对象进行存储,put方法中的第一个参数为映射关系中key的值,put方法的第二个参数为映射关系中value的值。
③ 利用HashMap的get方法获取key对应的value,然后强制类型转换为实际类型。get中的参数为key,返回值为key对应的value。
下表列出了HashMap中常用的方法:
返回类型 |
方法名称 |
作用 |
Object |
put(Object key,Object value) |
加入元素,返回与此key关联的原有的value,不存在则返回null |
void |
clear() |
从集合中移除所有的元素 |
boolean |
containsKey(Object key) |
根据key从集合中判断key是否存在 |
boolean |
containsValue(Object value) |
根据value从集合中判断value是否存在 |
Object |
get(Object key) |
根据key返回key对应的值 |
Set |
keySet() |
返回Map集合中包含的键集合 |
Object |
remove(Object key) |
从集合中删除key对应的元素,返回与key对应的原有value,不存在则返回null |
int |
size() |
返回集合中的元素的数量 |
表: HashMap常用方法
Map集合的综合示例:
代码演示:Map集合综合演示
import java.util.HashMap; import java.util.Scanner; public class TestMap { public static void main(String[] args) { HashMap map = new HashMap(); Scanner scanner = new Scanner(System.in); for (int i = 0; i < 5; i++) { System.out.println("请输入身份证号:"); String id = scanner.next(); System.out.println("请输入姓名:"); String name = scanner.next(); map.put(id, name); ① } int size = map.size(); ② System.out.println("数据输入完毕!共" + size + "条数据!\n---------------------------------"); String answer = "no"; do { System.out.println("请输入你要查找的用户的身份证号:"); String id = scanner.next(); if (map.containsKey(id)) { ③ String name = (String) map.get(id); ④ System.out.println("您查找的用户姓名为:" + name); } else { System.out.println("您查找的用户不存在!"); } System.out.println("您还要继续查找吗?(yes/no)"); answer = scanner.next(); } while ("yes".equalsIgnoreCase(answer)); System.out.println("请输入要删除的用户的身份证号:"); String id = scanner.next(); if (map.containsKey(id)) { String name = (String) map.remove(id); ⑤ System.out.println("用户" + name + "删除成功!"); } else { System.out.println("您要删除的用户不存在!"); } System.out.println("要格式化系统吗?(yes/no)"); String format = scanner.next(); if ("yes".equalsIgnoreCase(format)) { map.clear(); ⑥ System.out.println("系统格式化完毕!当前系统中数据为" + map.size() + "条"); } System.out.println("程序运行结束!"); } } |
代码解析:
① 使用put方法将身份证号和姓名存入Map集合中。
② 使用size方法获得集合中的映射关系条数。
③ 使用containsKey方法判断集合是否存在与key对应的映射关系。
④ 使用get方法获得身份证号对应的姓名。
⑤ 使用remove方法删除身份证号对应的用户,返回身份证号对应的姓名。
⑥ 使用clear方法删除Map集合中所有的映射关系。
来看下面的一个示例:
代码演示:Map集合中重复key
import java.util.HashMap; public class DemoMap { public static void main(String[] args) { HashMap map = new HashMap(); map.put("001", "小美"); map.put("002", "阿聪"); ① map.put("002", "小莉"); ② String name = (String) map.get("002"); System.out.println(name); } } |
注意①和②处的代码,在向集合中添加值的时候,使用了重复的key,但是value不同,在下面获得key“002”的value为多少呢?程序运行的结果是“小莉”。从结果可以中可以知道,Map集合中的key不能是重复的,如果重复,那么后面添加的映射关系会覆盖前面的映射关系。导致这样情况的出现主要是因为Map集合中的key的维护是依靠Set集合(马上会学习到)完成的。
HashMap和Hashtable的操作是相同的,他们的区别如下:
? Hashtable是线程安全的,HashMap是非线程安全的。所有HashMap比Hashtable的性能更高。
? Hashtable不允许使用使用null值作为key或value,但是HashMap是可以的。
2. Set集合
Set集合和List集合的很多的用法是相同的。但是Set集合中的元素是无序的,元素也是不能重复的。Set集合中常用类为HashSet。
HashSet类中常用的方法如下:
返回类型 |
方法名称 |
作用 |
boolean |
add(Object obj) |
加入元素 |
void |
clear() |
移除Set集合中所有元素 |
boolean |
contains(Object obj) |
判断Set集合中是否包含指定元素 |
boolean |
isEmpty() |
判断Set集合是否为空 |
Iterator |
iterator() |
返回Set集合中对元素迭代的迭代器 |
boolean |
remove(Object obj) |
从集合中删除元素 |
Int |
size() |
返回集合中的元素数量 |
表: HashSet类常用方法
通过上面的表,可以清楚的看到Set集合的用法和List集合是相似的,但是需要注意Set集合的迭代和List集合是不同的,List的集合的迭代可以通过for循环获得索引来进行,但是Set集合的迭代必须要通过迭代器进行。
代码演示:Set集合的迭代
import java.util.HashSet; import java.util.Iterator; public class SetIterator { public static void main(String[] args) { HashSet set = new HashSet(); set.add("a"); set.add("b"); set.add("c"); Iterator iter = set.iterator(); ① while (iter.hasNext()) { ② String str = (String) iter.next(); ③ System.out.println(str); } } } |
代码解析:
① 通过Set集合的iterator()方法获得该集合的迭代器,迭代器是Iterator类的实例。
② 根据迭代器的hasNext()方法判断集合中是否还有元素,如果有就返回true。
③ 根据迭代器的next()方法获得集合中的元素,并强制类型转换为目标类型。
从上面例子的运行结果,可以看出Set中的元素是无序的。通过Set集合的迭代再来学习Map集合的迭代。
代码演示:Map集合的迭代
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class MapIter { public static void main(String[] args) { HashMap map = new HashMap(); map.put("001", "小美"); map.put("002", "阿聪"); map.put("003", "小黑"); HashSet keys = (HashSet) map.keySet(); ① Iterator iter = keys.iterator(); while (iter.hasNext()) { String key = (String) iter.next(); ② String value = (String) map.get(key); ③ System.out.println(key + ":" + value); } } } |
代码解析:
① 调用Map集合的keySet方法获得Map集合中的key的集合。
② 获得key。
③ 根据key获得对应的value。
下面通过一个示例演示Set集合中不允许元素重复的特性:
代码演示:向Set集合中添加重复元素
import java.util.HashSet; import java.util.Iterator; public class Demo2 { public static void main(String[] args) { HashSet set = new HashSet(); set.add("a"); set.add("a"); set.add("c"); System.out.println("集合长度为:" + set.size()); Iterator iter = set.iterator(); while (iter.hasNext()) { String str = (String) iter.next(); System.out.println(str); } } } |
上面的代码输出集合的长度为2,而且集合中的元素只有一个a和c,从结果中可以看出Set集合中的元素是不能重复的。带着这个结论再来看下面的示例:
代码演示:向Set集合中添加重复元素
import java.util.HashSet; import java.util.Iterator; public class Demo3 { public static void main(String[] args) { Person personA = new Person("001", "Tom"); Person personB = new Person("001", "Tom"); HashSet set = new HashSet(); set.add(personA); set.add(personB); System.out.println("集合中元素个数:" + set.size()); Iterator iter = set.iterator(); while (iter.hasNext()) { Person p = (Person) iter.next(); System.out.println(p.cardId + ":" + p.name); } } } |
程序的运行结果如下:
集合中元素个数:2 001:Tom 001:Tom |
发现程序的运行结果是有“问题”的,因为Set集合中是不允许存放重复的元素的,但是两个Person对象的属性值是完全相同的,怎么还都能存放进去呢?要找到问题的答案,需要了解下Set集合的存放原理。
图: Set集合存储
从上图中可以看到,Set集合中的元素的无序性,但是Set集合是怎么判断每个元素的存放的位置呢?在向Set集合中存放元素时,Set集合根据元素的hashCode()方法来获取一个int类型的数据,然后根据这个数据来计算元素在集合中的位置。但是在存储元素时会出现两个元素的hashCode()方法返回值相同的情况,比如上图的对象C和D就出现了这种情况,导致计算出元素在集合中的位置相同,这种情况称之为“冲突”。如果发生了冲突,Set集合会根据发生冲突元素之间调用equals()方法进行比较,如果equals()返回值为true,说明两个元素为相同的元素,这样会导致添加操作无效。如果equals()返回值为false,说明两个元素不相同,这样Set集合会将该元素进行偏移存储。“冲突”发生的频率越高,Set集合的性能就越低,要尽可能的避免冲突的发生, 就要在类中重写hashCode()方法,并且要尽可能的保证hashCode()方法返回值是唯一的。在重写hashCode()方法时有个技巧,就是让对象中的数值属性和一个素数相乘,并将积相加,对于对象类型,调用其hashCode()方法即可。
对于hashCode()和equals()两个方法有这样的规律,hashCode()方法返回值相同时,equals()方法比较并不一定相等,但是equals()方法比较相等,hashCode()方法返回值是相同的。
代码演示:实现Person对象的equals和hashCode方法
public class Person { String cardId; String name; public Person(String cardId, String name) { this.cardId = cardId; this.name = name; } public int hashCode() { return cardId.hashCode() + name.hashCode(); } public boolean equals(Object obj) { if (obj == null){ return false; } if(obj instanceof Person){ Person other = (Person) obj; if (cardId == null) { if (other.cardId != null){ return false; } } else if (!cardId.equals(other.cardId)){ return false; } if (name == null) { if (other.name != null){ return false; } } else if (!name.equals(other.name)){ return false; } }else{ return false; } return true; } } |
再次运行Demo3的代码,运行结果如下:
集合中元素个数:1 001:Tom |
3. 本章总结
? Map集合用于保存具有映射关系的数据,即以键值对(key->value)的方式来存储数据。因此在Map集合内部有两个集合,一个集合用于保存Map中的key(键),一个集合用于保存Map中的value(值),其中key和value可以是任意数据类型数据。
? Set集合的特点。
? Set集合的使用及迭代。
? Map集合的迭代。
JAVA集合LIST MAP SET详解的更多相关文章
- Java集合04——fail-fast&fail-safe 详解
在前几个回合中,我们已经详细了解过了 Java 集合中的List.Set 和 Map,对这部分内容感兴趣的朋友可以关注我的公众号「Java面典」了解.今天我们将为各位介绍集合的失败机制--fail-f ...
- Java集合——TreeMap源码详解
)TreeMap 是一个有序的key-value集合,它是通过红黑树实现的.因为红黑树是平衡的二叉搜索树,所以其put(包含update操作).get.remove的时间复杂度都为log(n). (2 ...
- Java集合——ArrayList源码详解
) ArrayList 实现了RandomAccess, Cloneable, java.io.Serializable三个标记接口,表示它自身支持快速随机访问,克隆,序列化. public clas ...
- Java集合——LinkedHashMap源码详解
个KV.LinkedHashMap不仅像HashMap那样对其进行基于哈希表和单链表的Entry数组+ next链表的存储方式,而且还结合了LinkedList的优点,为每个Entry节点增加了前驱和 ...
- Java集合——LinkedList源码详解
)LinkedList直接继承于AbstractSequentialList,同时实现了List接口,也实现了Deque接口. AbstractSequentialList为顺序访问的数据存储结构提供 ...
- java的集合框架最全详解
java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作 ...
- GoLang基础数据类型--->字典(map)详解
GoLang基础数据类型--->字典(map)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是 ...
- Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...
- Java面试题04-final关键字详解
Java面试题04-final关键字详解 本篇博客将会讨论java中final关键字的含义,以及final用在什么地方,感觉看书总会有一些模糊,而且解释的不是很清楚,在此做个总结,以备准备面试的时候查 ...
随机推荐
- 使用SecureCRT网络连接树莓派
为了更加方便可以通过网络来连接.控制树莓派,使用SecureCRT可以通过网络来连接树莓派. 1.在树莓派上通过终端命令ifconfig 来查看当前树莓派的IP地址: IP地址 ...
- Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_PRC_CI_AS" in the equal to operation.
Scenario : 这个问题是我的存储过程中用到临时表时发生的. 应该是sql server 服务器的排序规则 (SQL_Latin1_General_CP1_CI_AS ) 与数据库的排序规则(C ...
- linux查看网卡个数及速度
# lspci | grep Ethernet03:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5708 Gigabi ...
- Qt 多线程与数据库操作需要注意的几点问题(QSqlDatabase对象只能在当前线程里使用)
彻底抛弃MFC, 全面应用Qt 已经不少时间了.除了自己看书按步就班做了十几个验证性的应用,还正式做了3个比较大的行业应用,总体感觉很好.Native C++ 下, Qt 基本是我用过的最简便的界面库 ...
- Delphi XE6 通过JavaScript API调用百度地图
参考昨天的内容,有朋友还是问如何调用百度地图,也是,谁让咱都在国内呢,没办法,你懂的. 首先去申请个Key,然后看一下百度JavaScript的第一个例子:http://developer.baidu ...
- 一步一步学习SignalR进行实时通信_4_Hub
原文:一步一步学习SignalR进行实时通信_4_Hub 一步一步学习SignalR进行实时通信\_4_Hub SignalR 一步一步学习SignalR进行实时通信_4_Hub 前言 创建Hub 配 ...
- Linux下利用fork()创建子进程并使父进程等待子进程结束
int status; pid_t t = fork(); if(t){ waitpid(t, &status, 0); }else{ system("vi temp ...
- 有关UNICODE、ANSI字符集和相关字符串操作
Q UNICODE字符串如何显示 A 如果程序定义了_UNICODE宏直接用 WCHAR *str=L"unicodestring"; TextOut(0,0,str); 否则就需 ...
- StarTeam SDK 13 下载安装
SDK 13据称兼容 StarTeam 11. 下载地址是:ftp://us.ftp.microfocus.com/Starteam/st-sdk-13.0-readme.htm Java用户可以选在 ...
- SSH登陆服务器的简单命令
SSh 用户名@目标Ip: 回车输入密码: