------- android培训java培训、期待与您交流! ----------

一、集合概念

  相信大家都知道,java是一门面向对象的编程语言,而对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储进行存储,集合就是存储对象最常用的一种方式,我们可以把集合看成是一个容器。

  同样,数组也是一种容器,那么集合和它有什么不同?

  1.数组虽然也可以存储对象,但是长度是固定的,而集合长度是可变的。
  2.数组中可以存储基本数据类型数据,集合只能存储对象。
  3.数组中储存的基本数据类型数据或对象要类型相同,而集合可以存储不同类型的对象。

  所以,当事先不知道要存放数据的个数,或者需要一种比数组下标存取机制更灵活的方法时,就需要用到集合类。

二、集合的构成与分类

下面是一张网上找到的图片,对于集合中的类和接口有比较清晰的表现:

  1.Collection接口:

  Collection是最基本的集合接口,一个Collection代表一组对象,即Collection的元素(Elements)。一些 Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java JDK不提供直接继承自Collection的类,Java JDK提供的类都是继承自Collection的”子接口“如List和Set。

  所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,另一个 Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。其实后一个构造函数就是复制一个Collection。

  那么如何取出Collection中的元素?无论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代器,使用该迭代器即可逐一访问Collection中每一个元素。典型的用法如下:

     Iterator it = collection.iterator(); // 获得一个迭代器。
    while(it.hasNext()) { //通过迭代器判断集合中是否还有元素。
      Object obj = it.next(); // 得到下一个元素,类型为Object。
    }

  Collection定义了集合框架的共性功能(方法):
  ①添加:add(e);  addAll(collection);
  ②删除:remove(e);  removeAll(collection);  clear();
  ③判断:contains(e);  isEmpty();
  ④获取:iterator();  size();
  ⑤获取交集:retainAll();
  ⑥集合变数组:toArray();

  Collection接口派生的两个接口是List和Set。

  (1)List接口

  List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。List允许有相同的元素,List集合判断元素是否相同是通过对象的equals()方法。

  除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素, 还能向前或向后遍历。

  实现List接口的常用类有ArrayList,LinkedList,Vector。

  ArrayList类:

  ArrayList实现了可变大小的数组。它允许所有元素,包括null。

  每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组(数组结构)的大小。这个容量可随着不断添加新元素而自动增加。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。

  注意ArrayListList是非同步的,如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改了该列表,则它必须保持外部同步。一种解决方法是在创建ArrayList时构造一个同步的List来包装它: 

     List list = Collections.synchronizedList(new ArrayList(...));  

  数组结构(每个元素都有角标):

  LinkedList类:

  LinkedList实现了List接口,存储数据的方式是双链表,允许null元素。此外LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。

  注意LinkedList是非同步的,如果多个线程同时访问一个链接列表,而其中至少一个线程从结构上修改了该列表,则它必须保持外部同步。一种解决方法是在创建LinkedList时构造一个同步的List来包装它:

   List list = Collections.synchronizedList(new LinkedList(...));

  双链表结构(每个元素只知道前后的元素):

  Arraylist和Linkedlist的不同处:
  ①ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
  ②对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。
  ③对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

  Vector类:

  Vector非常类似ArrayList,也是数组结构存储数据,但是Vector是同步的。由Vector创建的Iterator,虽然和 ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了 Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出 ConcurrentModificationException,因此必须捕获该异常。同样,当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。另外,Vector还有特有的取出元素的方式,通过它的elements()获取Enumeration枚举来得到元素,实际上Enumeration和Iterator功能是一样的。

  Vector与ArrayList不同之处是:
  ①Vector是线程同步的,所以它也是线程安全的,而Arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。
  ②如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。
  ③Vector还有特有的取出元素的方式,Enumeration枚举。

  (2)Set接口  

  Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。

  另外要注意,必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object1.equals(Object2)=true将导致一些问题。

  实现Set接口的常用类有HashSet和TreeSet。

  HashSet类:

  Hashset存储数据的结构是哈希表,它不保证 set 的迭代顺序,特别是它不保证该顺序恒久不变。也就是说,HashSet中的元素是无序的。它是通过元素的hashCode()和equals()方法来保证元素的唯一性。如果元素的hashCode值不同,则不需调用equals()进行比较。如果元素的HashCode值相同,才会调用equals()判断两个元素是否相同。基于这种唯一性标准,HashSet中判断元素是否存在,以及删除等操作,依赖的方法也是元素的hashCode()和equals()方法。

  注意HashSet是非同步的,如果多个线程同时访问一个HashSet,而其中至少一个线程修改了该 set,那么它必须 保持外部同步。一种解决方法是在创建HashSet时构造一个同步的Set来包装它:

     Set s = Collections.synchronizedSet(new HashSet(...));

  哈希表结构(当元素比较hashCode不同时,元素处于不同区域;当元素比较hashCode相同,equals比较不同时,元素会在同个区域):

  TreeSet类:

  TreeSet存储数据的结果是二叉树(红黑树),基于实现NavigableSet接口,它是使用元素的自然顺序对元素进行排序(当元素自身具有比较性时),或者根据创建 set 时提供的 Comparator进行排序(当元素自身不具备比较性,或者比较性不合需求时),具体取决于使用的构造方法。也就是说,TreeSet中的元素是有序的。它是通过元素的compareTo()或者构造时使用的比较器Comparator中的compare()方法来保证元素的唯一性。

  注意TreeSet是非同步的,如果多个线程同时访问一个TreeSet,而其中至少一个线程修改了该 set,那么它必须 外部同步。一种解决方法是在创建TreeSet时构造一个同步的Set来包装它:

     SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...)); 

  二叉树结构(比较后,小的元素在左子树,大的元素在右子树):

  

  2.Map接口

  Map没有继承Collection接口,Map提供key(键)到value(值)的映射。一个Map中不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。映射顺序定义为迭代器在映射的 collection 视图上返回其元素的顺序。某些映射实现可明确保证其顺序,如 TreeMap 类;另一些映射实现则不保证顺序,如 HashMap 类。Map集合没有直接取出元素的方法,想获取Map集合中的元素,需要先用entrySet()方法获取键-值映射关系的Set集合,或者使用keySet()方法获取键的Set集合。

  Map集合的共性功能(方法):
  ①添加:put(K key, V value);  putAll(Map<? extends K,? extends V> m);
  ②删除: remove(Object key);  clear();
  ③判断:containsValue(Object value);  containsKey(Object key);  isEmpty();
  ④获取:get(Object key);  size();  values();  entrySet();  keySet();

  实现Map接口的常用类有HashMap,TreeMap。

  HashMap类:

  基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用null键和null值(替代Hashtable)。其键集上的对象是通过元素的hashCode()和equals()方法来保证元素的唯一性。如果元素的hashCode值不同,则不需调用equals()进行比较。如果元素的HashCode值相同,才会调用equals()判断两个元素是否相同。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

  注意HashMap是非同步的,如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须保持外部同步。一种解决方法是在创建HashMap时构造一个同步的Map来包装它:

    Map m = Collections.synchronizedMap(new HashMap(...));

  TreeMap类:

  基于二叉树的 Map 接口的实现。它所包含的映射关系是有序的(以键为标准),其键的排序方式和TreeSet中的元素相同。

  注意TreeMap是非同步的,如果多个线程同时访问一个映射,并且其中至少一个线程从结构上修改了该映射,则其必须外部同步。一种解决方法是在创建TreeMap时构造一个同步的Map来包装它:

     SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));

三、集合的应用

1.例子一(将自定义对象作为元素存到ArrayList集合中,并去除重复元素):

 import java.util.ArrayList;
import java.util.Iterator; /*
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。 思路:
1,对人描述,将数据封装进人对象。
2,定义容器,将人存入。
3,取出。 List集合判断元素是否相同,依据是元素的equals方法。
*/
class Person {
private String name;
private int age;
Person(String name,int age) {
this.name = name;
this.age = age;
} public boolean equals(Object obj) {
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
} public class ArrayListTest {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<Person>(); //使用泛型指定集合元素类型。 al.add(new Person("lisi01",30));
al.add(new Person("lisi02",32));
al.add(new Person("lisi02",32));
al.add(new Person("lisi04",35));
al.add(new Person("lisi03",33));
al.add(new Person("lisi04",35)); al = singleElement(al);
System.out.println("remove 03 :"+al.remove(new Person("lisi03",33)));//remove方法底层也是依赖于元素的equals方法。 Iterator<Person> it = al.iterator();
while(it.hasNext()) { //判断集合中是否还有元素。
Person p = it.next();
System.out.println(p.getName()+"::"+p.getAge());
}
} // 去掉重复元素。
public static ArrayList<Person> singleElement(ArrayList<Person> al) {
//定义一个临时容器。
ArrayList<Person> newAl = new ArrayList<Person>();
Iterator<Person> it = al.iterator();
while(it.hasNext()) {
Person p = it.next(); if(!newAl.contains(p))
newAl.add(p);
}
return newAl;
}
}

运行结果为:

remove 03 :true
lisi01::30
lisi02::32
lisi04::35

2.例子二(使用LinkList模拟一个堆栈或者队列数据结构):

 import java.util.LinkedList;

 /*
使用LinkList模拟一个堆栈或者队列数据结构。 堆栈:先进后出,如同一个杯子。
队列:先进先出,如同一个水管。
*/
class DuiLie {
private LinkedList link;
private LinkedList link_2; DuiLie() {
link = new LinkedList();
link_2 = new LinkedList();
} public void myAdd(Object obj) {
link.addFirst(obj);
link_2.addFirst(obj);
} public Object myGet() {
return link.removeFirst();
} public Object myGet_2() {
return link.removeLast();
} public boolean isNull() {
if (link.isEmpty()) {
try {
return link.isEmpty();
}
finally {
link.addAll(link_2);
}
}
return link.isEmpty();
}
} public class LinkedListTest {
public static void main(String[] args) {
DuiLie dl = new DuiLie(); dl.myAdd("java01");
dl.myAdd("java02");
dl.myAdd("java03");
dl.myAdd("java04"); //堆栈形式;先进后出
while (!dl.isNull())
System.out.println(dl.myGet());
System.out.println(); //队列形式:先进先出
while (!dl.isNull())
System.out.println(dl.myGet_2());
}
}

运行结果为:

java04
java03
java02
java01

java01
java02
java03
java04

3.例子三(Vector枚举):

 import java.util.Enumeration;
import java.util.Vector; /*
枚举就是Vector特有的取出方式。
发现枚举和迭代器很像。
其实枚举和迭代是一样的。 因为枚举的名称以及方法的名称都过长。
所以被迭代器取代了。
*/
public class VectorDemo {
public static void main(String[] args) {
Vector<String> v = new Vector<String>(); v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04"); Enumeration<String> en = v.elements();
while(en.hasMoreElements()) { //判断集合中是否还有元素。
System.out.println(en.nextElement());
}
}
}

运行结果为:

java01
java02
java03
java04

4.例子四(往HashSet集合中存入自定义对象):

 import java.util.HashSet;
import java.util.Iterator; /*
往HashSet集合中存入自定义对象。
以人为例:
姓名和年龄相同视为同一个人,重复元素。
*/
public class HashSetTest {
public static void main(String[] args) {
HashSet<Person> hs = new HashSet<Person>(); hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a2",12));
// 查看是否包含指定元素。
System.out.println("a1:"+hs.contains(new Person("a2",12)));
// 删除一个元素。
System.out.println(hs.remove(new Person("a3",13))); Iterator<Person> it = hs.iterator();
while (it.hasNext()) {
Person p = it.next();
System.out.println(p.getName()+"..."+p.getAge());
}
}
} class Person {
private String name;
private int age; Person(String name,int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public int getAge() {
return age;
} public int hashCode() {
return name.hashCode()+age*39;
} public boolean equals(Object obj) {
if (!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
}

运行结果为:

a1:true
true
a2...12
a1...11

5.例子五(使用TreeSet添加字符串,字符串按长度排序):

 import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet; /*
按照字符串长度排序。 字符串本身具备比较性,但是它的比较方式不是所需要的。
这时只能使用比较器。
*/
public class TreeSetTest {
public static void main(String[] args) {
// 元素本身的比较性不合需求,构造时加上比较器。
TreeSet<String> ts = new TreeSet<String>(new StrLenCompare()); ts.add("abcd");
ts.add("cc");
ts.add("cba");
ts.add("aaa");
ts.add("z");
ts.add("hahaha"); Iterator<String> it = ts.iterator();
while (it.hasNext())
{
String s = (String)it.next();
System.out.println(s+"...length..."+s.length());
}
}
} //比较器比较内容。
class StrLenCompare implements Comparator<String> {
public int compare(String s1,String s2) {
int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
if (num==0)
return s1.compareTo(s2);
return num;
}
}

运行结果为:

z...length...1
cc...length...2
aaa...length...3
cba...length...3
abcd...length...4
hahaha...length...6

6.例子六(使用HashMap添加不重复的元素(映射关系)):

 import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set; /*
每一个学生都与对应的归属地。
学生Student,地址String。
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。 思路:
1,描述学生。
2,因为学生和地址存在映射关系。定义Map容器,将学生作为键,地址作为值存入。
3,获取Map集合中的元素。
*/
class Student implements Comparable<Student> {
private String name;
private int age;
Student(String name,int age) {
this.name = name;
this.age = age;
} public int compareTo(Student s) {
int num = new Integer(this.age).compareTo(new Integer(s.age));
if (num==0) {
return this.name.compareTo(s.name);
}
return num;
} public int hashCode() {
return this.name.hashCode()+this.age*34;
} public boolean equals(Object obj) { //这里重写的是父类Object的equals方法,参数类型必须Object,否则重写失败。
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s = (Student)obj;
return this.name.equals(s.name) && this.age==s.age;
} public String getName() {
return name;
} public int getAge() {
return age;
} public String toString() {
return name+":::"+age;
}
} public class HashMapTest {
public static void main(String[] args) {
HashMap<Student,String> hm = new HashMap<Student,String>(); hm.put(new Student("lisi1",21),"beijing");
hm.put(new Student("lisi1",21),"tianjin");
hm.put(new Student("lisi2",22),"shanghai");
hm.put(new Student("lisi3",23),"nanjing");
hm.put(new Student("lisi4",24),"wuhan"); //第一种取出方式:keySet
Set<Student> keySet = hm.keySet();
Iterator<Student> it = keySet.iterator(); while (it.hasNext()) {
Student s = it.next();
String addr = hm.get(s);
System.out.println(s+"..."+addr);
}
System.out.println(); /* //第二种取出方式:entrySet
Set<Map.Entry<Student,String>> entrySet = hm.entrySet();
Iterator<Map.Entry<Student,String>> iter = entrySet.iterator(); while (iter.hasNext()) {
Map.Entry<Student,String> me = iter.next();
Student s = me.getKey();
String addr = me.getValue();
System.out.println(s+"....."+addr);
}*/
}
}

运行结果为:

lisi3:::23...nanjing
lisi1:::21...tianjin
lisi2:::22...shanghai
lisi4:::24...wuhan

7.例子七(使用TreeMap添加有序的元素(映射关系)):

 import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap; /*
需求:每一个学生都与对应的归属地。
学生Student,地址String。
学生属性:姓名,年龄。
对学生对象的年龄进行升序排序。 因为数据是以键值对形式存在的。
所以要是哟昂可以排序的Map集合,TreeMap。
*/
class StuNameComparator implements Comparator<Student> {
public int compare(Student s1,Student s2) {
int num = s1.getName().compareTo(s2.getName());
if (num==0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
return num;
}
} public class TreeMapTest {
public static void main(String[] args) {
//因为Student本身定义有比较性,可以直接满足需求。如果是按姓名排序,则需要加上StuNameComparator比较器。
TreeMap<Student,String> tm = new TreeMap<Student,String>(/*new StuNameComparator()*/); tm.put(new Student("blisi3",23),"nanjing");
tm.put(new Student("lisi1",21),"beijing");
tm.put(new Student("alisi14",24),"wuhan");
tm.put(new Student("lisi1",21),"tianjin");
tm.put(new Student("alisi11",21),"tianjin");
tm.put(new Student("alisi12",22),"shanghai"); Set<Map.Entry<Student,String>> entrySet = tm.entrySet();
Iterator<Map.Entry<Student,String>> it = entrySet.iterator();
while (it.hasNext()) {
Map.Entry<Student,String> me = it.next();
Student s = me.getKey();
String addr = me.getValue();
System.out.println(s+"..."+addr);
}
}
} class Student implements Comparable<Student> {
private String name;
private int age;
Student(String name,int age) {
this.name = name;
this.age = age;
} public int compareTo(Student s) {
int num = new Integer(this.age).compareTo(new Integer(s.age));
if (num == 0) {
return this.name.compareTo(s.name);
}
return num;
} public int hashCode() {
return this.name.hashCode()+this.age*34;
} public boolean equals(Object obj) {
if(!(obj instanceof Student))
throw new ClassCastException("类型错误");
Student s = (Student)obj;
return s.name.equals(this.name) && this.age == s.age;
} public String getName() {
return name;
} public int getAge() {
return age;
} public String toString() {
return name+":::"+age;
}
}

运行结果为:

alisi11:::21...tianjin
lisi1:::21...tianjin
alisi12:::22...shanghai
blisi3:::23...nanjing
alisi14:::24...wuhan

四、总结

  如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
  如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类或者在类意外加上同步。
  要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
  尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。

黑马程序员_Java基础:集合总结的更多相关文章

  1. 黑马程序员_Java基础视频-深入浅出精华版--PPT 文件列表

    \day01\code\第一章_Java概述.ppt;\day01\resource\资料\50道编程题(有精力的同学看看).doc;\day01\resource\资料\Sun_Java程序员认证考 ...

  2. 黑马程序员_Java基础组成

    Java语言基础组成 2.1关键字 main不是关键字,但被JVM所识别的名称. 关键字的定义和特点 定义:被Java语言赋予了特殊含义的单词. 特点:关键字中所有字母都为小写. 用于定义数据类型的关 ...

  3. 黑马程序员_Java基础:网络编程总结

    ------- android培训.java培训.期待与您交流! ---------- Java语言是在网络环境下诞生的,它是第一个完全融入网络的语言,虽然不能说它是对支持网络编程做得最好的语言,但是 ...

  4. 黑马程序员_java基础笔记(06)...集合

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— JavaApi(其实就是java给我们提供的已经定义好的对象.工具对象:集合框架) ...

  5. 黑马程序员_Java基础:反射机制(Reflection)总结

    ------- android培训.java培训.期待与您交流! ---------- 反射在java中有非常重大的意义,它是一种动态的相关机制,可以于运行时加载.探知.使用编译期间完全未知的clas ...

  6. 黑马程序员_Java基础:IO流总结

    ------- android培训.java培训.期待与您交流! ---------- IO流在是java中非常重要,也是应用非常频繁的一种技术.初学者要是能把IO技术的学透,java基础也就能更加牢 ...

  7. 黑马程序员_Java基础常识

    一.基础常识 1,软件开发 1)什么是软件?软件:一系列按照特定顺序组织的计算机数据和指令的集合. 常见的软件 系统软件 如:DOS,windows,Linux等. 应用软件: 如:扫雷,迅雷,QQ等 ...

  8. 黑马程序员_Java基础视频-深入浅出精华版--视频列表

    \day01\avi\01.01_计算机基础(计算机概述).avi; \day01\avi\01.02_计算机基础(计算机硬件和软件概述).avi; \day01\avi\01.03_计算机基础(软件 ...

  9. 课程2:《黑马程序员_Java基础视频-深入浅出精华版》-视频列表-

    \day01\avi\01.01_计算机基础(计算机概述).avi; \day01\avi\01.02_计算机基础(计算机硬件和软件概述).avi; \day01\avi\01.03_计算机基础(软件 ...

随机推荐

  1. etc这个目录

    自己对他的记忆最深了,因为每次你添加新的软件向电脑里时,软件都会有一个自己的配置文件,那么你修改这个配置文件的某个选项,就可以改变软件的某个功能. 或者是某个外设都有自己的配置文件. 其实这个配置文件 ...

  2. 设置centos7默认运行级别

    1.查看当前运行级别 systemctl get-default 2.设置命令行运行级别 systemctl set-default multi-user.target 3.设置图形化运行级别 sys ...

  3. VS工程里的文件都是啥?如何打包? 2015-03-04

    打完补充:以下内容全部是我一家之言,只是愿意分享,内容如有不妥还请见谅. ====================================================== 刚才接收了一份代 ...

  4. javax/javaee-api/ Maven依赖

    <dependency>    <groupId>javax</groupId>    <artifactId>javaee-api</artif ...

  5. 根目录97 <input file>标签,把图片上传到服务器(跟增删改查一起实现)

    首先来个简单的html页面: enctype="multipart/form-data" encoding="multipart/form-data" acti ...

  6. Git学习(四)——分支管理

    一.创建与合并分支 1.创建分支 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点.每次提交 ,mast ...

  7. ajaxFileUpload 异步上传数据

    AjaxFileUpload.js并不是一个很出名的插件,只是别人写好的放出来供大家用,原理都是创建隐藏的表单和iframe然后用JS去提交,获得返回值. 它的配置方式比较像jQuery的AJAX,使 ...

  8. netcat使用

    一.端口监听(实时消息) 首先在A计算机上,它充当的是服务器角色,$ nc -l 3333 这时就创建了一个监听端口(listening socket(server)).- -l 它让 nc 监听一个 ...

  9. 使用dom元素和jquery元素实现简单增删改的练习

    软件开发实际就是数据的增删改查,javascript前端开发也不例外.今天学了jquery框架的简单使用.于是用它实现简单的增删改,接着也用原始的javascript实现同样的功能,以便看出jquer ...

  10. REDIS源码中一些值得学习的技术细节01

    redis.c/exitFromChild函数: void exitFromChild(int retcode) { #ifdef COVERAGE_TEST exit(retcode); #else ...