Map基本概念

数据结构中Map是一种重要的形式。Map接口定义的是查询表,或称查找表,其用于储存所谓的键/值对(key-value pair),其中key是映射表的索引。

JDK结构中还存在实现Map类似功能的遗留集合:

Hashtable(线程安全的散列映射表)

Properties(属性映射表),常用于配置文件(如db.properties)。

Map接口源代码

  1. package java.util;
  2.  
  3. /* 映射表(查询表)泛型接口 */
    public interface Map<K,V> {
  4. /* 基本与Collection相同,返回映射表中key-value映射对数量(内部属性size) */
  5. int size();
  6. /* 基本与Collection相同,返回映射表是否包含映射对 */
  7. boolean isEmpty();
  8. /* 返回映射表是否包含指定的键 */
  9. boolean containsKey(Object key);
  10. /* 返回映射表是否包含指定的值,或者说指定的值是否有大于等于1个映射的键 */
  11. boolean containsValue(Object value);
  12. /* 如果映射表中存在指定key,返回此key的值;否则,返回null */
  13. V get(Object key);
  14. /* 将键值对放入映射表中。
    * 如果键存在,则用现在的值替换原有值,返回原有值对象;
    * 如果键不存在则存入键值对,返回null */
    */
  15. V put(K key, V value);
  16. /* 移除指定键对应的值。如果存在键,则移除,并返回移除值对象;反之,则返回null */
  17. V remove(Object key);
  18. /* 复制另一张映射表元素到本映射表中 */
  19. void putAll(Map<? extends K, ? extends V> m);
  20. /* 基本同Collection,清空映射表 */
  21. void clear();
  22. /* 获得键的Set集合 */
  23. Set<K> keySet();
  24. /* 获得值的Collection集合 */
  25. Collection<V> values();
  26. /* 获得键值对的Set集合 */
  27. Set<Map.Entry<K, V>> entrySet();
  28. /* 内部接口 Entry<K,V> */
  29. interface Entry<K,V> {
  30. /* 获取键值对的键 */
  31. K getKey();
  32. /* 获取键值对的值 */
  33. V getValue();
  34. /* 设置键值对的值 */
  35. V setValue(V value);
  36. /* 比较entry(键值对) */
  37. boolean equals(Object o);
  38. /* 生成entry对象的hash值 */
  39. int hashCode();
  40. }
  41. /* 比较映射表 */
  42. boolean equals(Object o);
  43. /* 生成映射表对象的hash码*/
  44. int hashCode();
  45. }

深入理解码源

对象比较好基友:equals(Object obj)hashcode()

Map<K, V>接口及其内部接口Entry<K, V>都有这俩方法。如此设计,目的就是规范其实现子类,要求子类必须重写Object类的这俩方法,从而完成映射表这种数据结构的既定思想。

  1. boolean equals(Object o); // 对象比较
  2. int hashCode(); // 哈希码

集合框架通用方法:size()isEmpty()

集合框架(包括Collection接口及其子接口ListSetMap接口)内部维护一个size属性,其描述用户提供可操纵元素数量,通过size()方法向用户提供可见性,通过isEmpty()方法向用户说明是否集合中仍存在其可操纵的元素。

  1. int size(); // 元素保有量
  2. boolean isEmpty(); // 元素数量是否为0

键、值存在性判断:containsKey(Object key)containsValue(Object value)

  1. boolean containsKey(Object key); // 映射表是否包含指定键的元素
  2. boolean containsValue(Object value); // 映射表是否包含指定值得元素

映射表增删查改:

增、改  V put(K key, V value)  V putAll(Map<? extends K, ? value V> m)

删        V remove(Object key)   void clear()

查        V get(Object key)

  1. V put(K key, V value) // 放入或替换指定key的键值对
  2. V putAll(Map<? extends K, ? value V> m) // 将另一映射表所有元素放入本映射表
  3. V remove(Object key) // 移除指定key的键值对
  4. V get(Object key) // 获取指定key的键值对
  5. void clear() // 清除所有映射表元素
  1. package com.forget406.study;
  2.  
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import java.util.TreeMap;
  6.  
  7. public class MapStudy {
  8. @SuppressWarnings({ "unchecked", "rawtypes" })
  9. public static void main(String[] args) {
  10. /* JDK 1.7允许后面的尖括号内不写泛型变量 */
  11. Map<String, Coordinate> rect =
  12. new HashMap<>();
  13. rect.put("point A", new Coordinate(0, 0));
  14. rect.put("point B", new Coordinate(1, 0));
  15. rect.put("point C", new Coordinate(1, 1));
  16. rect.put("point D", new Coordinate(0, 1));
  17.  
  18. Map<String, Coordinate> line =
  19. new TreeMap<String, Coordinate>();
  20. line.put("point A", new Coordinate(0, 0));
  21. line.put("point B", new Coordinate(3, 3));
  22.  
  23. /***** 实验测试部分 *****/
  24. System.out.println(rect); // output rectangle
  25. System.out.println(line); // output line
  26. System.out.println(rect.put("point D", new Coordinate(2, 2))); // (0, 1)
  27. System.out.println(rect.get("point C")); // (1,1)
  28. System.out.println(rect.get("point E")); // null
  29. rect.putAll(line);
  30. System.out.println(rect);
  31. System.out.println(line.remove("point C")); // null
  32. System.out.println(line.remove("point A")); // (0, 0)
  33. }
  34.  
  35. }
  36.  
  37. /**
  38. * 坐标类
  39. *
  40. * @author forget406
  41. * @since 09/08/2016
  42. * @param <T> 泛型参数
  43. */
  44. class Coordinate<T> {
  45. private T x;
  46. private T y;
  47.  
  48. public Coordinate(T x, T y) {
  49. this.x = x;
  50. this.y = y;
  51. }
  52.  
  53. @Override
  54. public int hashCode() {
  55. final int prime = 31;
  56. int result = 1;
  57. result = prime * result + ((x == null) ? 0 : x.hashCode());
  58. result = prime * result + ((y == null) ? 0 : y.hashCode());
  59. return result;
  60. }
  61.  
  62. @SuppressWarnings("unchecked")
  63. @Override
  64. public boolean equals(Object obj) {
  65. if (this == obj)
  66. return true;
  67. if (obj == null)
  68. return false;
  69. if (getClass() != obj.getClass())
  70. return false;
  71. Coordinate<T> other = (Coordinate<T>) obj;
  72. if (x == null) {
  73. if (other.x != null)
  74. return false;
  75. } else if (!x.equals(other.x))
  76. return false;
  77. if (y == null) {
  78. if (other.y != null)
  79. return false;
  80. } else if (!y.equals(other.y))
  81. return false;
  82. return true;
  83. }
  84.  
  85. @Override
  86. public String toString() {
  87. return "(" + x + "," + y + ")";
  88. }
  89. }
  1. {point C=(1,1), point B=(1,0), point A=(0,0), point D=(0,1)}
  2. {point A=(0,0), point B=(3,3)}
  3. (0,1)
  4. (1,1)
  5. null
  6. {point C=(1,1), point B=(3,3), point A=(0,0), point D=(2,2)}
  7. null
  8. (0,0)

程序运行结果

映射表元素遍历三种方式(或称 映射表集合视图(*)):

  • key遍历  Set<K> keySet()  返回映射表中所有键的视图。可以从这个Set中删除元素,同时也从映射表中删除了它们。   
  • value遍历  Collection<V> values() 返回映射表中所有值的视图。可以从这个Collection中删除元素,同时也从映射表中删除了它们。
  • Entry(key-value对)遍历  Set<Map.Entry<K, V>> entrySet() 返回Map.Entry对象Set集的视图,即映射表中的键/值对。可以从这个集合中删除元素,同时也从映射表中删除了它们。

注意:虽然可以从这三种遍历方式遍历获得的视图集合中删除元素,但是均不能够在其中添加元素。

  1. Set<K> keySet(); // 元素键视图集
  2. Collection<V> values(); // 元素值视图集
  3. Set<Map.Entry<K, V>> entrySet(); // 元素键/值对视图集

Map接口的内部接口,即Entry<K, V>接口,起封装键值对的作用。通过键值对遍历Map时,可以通过Entry接口提供的方法获取相应的键、值,以及设置键值对的值。

K getKey()   获得键值对的键

V getValue()  获得键值对的值

V setValue(V value)   设置键值对的值,同时映射表的内容也同时更新(*)

K setKey(K key)   但没有提供设置键值对键的方法,why? 键值对的键是键值对的索引,改变键不具有实际意义,而且改变之后会引起一系列诸如hash值改变等问题。

  1. /* Entry<K, V>接口,属于内部接口 */
    interface Entry<K,V> {
  2. K getKey(); // 获得键值对的键
  3. V getValue(); // 获得键值对的值
  4. V setValue(V value); // 设置键值对的值
  5. /* 前面已经论述过 */
  6. boolean equals(Object o);
  7. int hashCode();
  8. }
  1. import java.util.HashMap;
  2. import java.util.Map;
  3. import java.util.Map.Entry;
  4. import java.util.Set;
  5.  
  6. public class MapStudy {
  7. @SuppressWarnings({ "unchecked", "rawtypes" })
  8. public static void main(String[] args) {
  9. Map<String, Coordinate> rect =
  10. new HashMap<String, Coordinate>();
  11. rect.put("point A", new Coordinate(0, 0));
  12. rect.put("point B", new Coordinate(1, 0));
  13. rect.put("point C", new Coordinate(1, 1));
  14. rect.put("point D", new Coordinate(0, 1));
  15.  
  16. /***** 实验测试代码 *****/
  17. Set<Entry<String, Coordinate>> pos = rect.entrySet();
    /* 最好判断一下是否为null */
  18. if (pos != null) {
  19. for(Entry<String, Coordinate> p : pos) {
  20. System.out.println(p.getKey()+ "=" +p.getValue()); // 获得键、值
  21. p.setValue(new Coordinate("?", "?")); // 设置对应Entry的值
  22. }
  23. System.out.println(rect); // 更新Entry后,原来映射表内容也随之更新
  24. }
  25. }
  26. }
  27.  
  28. /**
  29. * 坐标类
  30. *
  31. * @author forget406
  32. * @since 09/08/2016
  33. * @param <T> 泛型参数
  34. */
  35. class Coordinate<T> {
  36. private T x;
  37. private T y;
  38.  
  39. public Coordinate(T x, T y) {
  40. this.x = x;
  41. this.y = y;
  42. }
  43.  
  44. @Override
  45. public int hashCode() {
  46. final int prime = 31;
  47. int result = 1;
  48. result = prime * result + ((x == null) ? 0 : x.hashCode());
  49. result = prime * result + ((y == null) ? 0 : y.hashCode());
  50. return result;
  51. }
  52.  
  53. @SuppressWarnings("unchecked")
  54. @Override
  55. public boolean equals(Object obj) {
  56. if (this == obj)
  57. return true;
  58. if (obj == null)
  59. return false;
  60. if (getClass() != obj.getClass())
  61. return false;
  62. Coordinate<T> other = (Coordinate<T>) obj;
  63. if (x == null) {
  64. if (other.x != null)
  65. return false;
  66. } else if (!x.equals(other.x))
  67. return false;
  68. if (y == null) {
  69. if (other.y != null)
  70. return false;
  71. } else if (!y.equals(other.y))
  72. return false;
  73. return true;
  74. }
  75.  
  76. @Override
  77. public String toString() {
  78. return "(" + x + "," + y + ")";
  79. }
  80. }
  1. point C=(1,1)
  2. point B=(1,0)
  3. point A=(0,0)
  4. point D=(0,1)
  5. {point C=(?,?), point B=(?,?), point A=(?,?), point D=(?,?)}

程序测试结果

如果读者需要进一步了解Java的内部接口机制,可以阅读另一篇文章:《Java高级特性(二)内部接口》

Map遍历方式

Map遍历作为文章体系中极为重要的一块内容,从上面模块中抽出来单独总结。

Iterator<E>接口实现

这种实现方式相对来说比较鸡肋,反正遍历Map我很少用到的。

  1. import java.util.Collection;
  2. import java.util.HashMap;
  3. import java.util.Iterator;
  4. import java.util.Map;
  5. import java.util.Map.Entry;
  6. import java.util.Set;
  7.  
  8. public class MapStudy {
  9. @SuppressWarnings({ "unchecked", "rawtypes" })
  10. public static void main(String[] args) {
  11. Map<String, Coordinate> rect =
  12. new HashMap<String, Coordinate>();
  13. rect.put("point A", new Coordinate(0, 0));
  14. rect.put("point B", new Coordinate(1, 0));
  15. rect.put("point C", new Coordinate(1, 1));
  16. rect.put("point D", new Coordinate(0, 1));
  17.  
  18. /***** Iterator<E>方式遍历代码 *****/
  19. // 遍历key,获取key
  20. Set<String> keys = rect.keySet();
  21. Iterator<String> it1 = keys.iterator();
  22. while(it1.hasNext()) { // 问
  23. String key = it1.next(); // 取
  24. System.out.println(key);
  25. // it1.remove(); 删
  26. }
  27.  
  28. // 遍历value,获取value
  29. Collection<Coordinate> values = rect.values();
  30. Iterator<Coordinate> it2 = values.iterator();
  31. while(it2.hasNext()) {
  32. Coordinate value = it2.next();
  33. System.out.println(value);
  34. }
  35.  
  36. // 遍历key-value对,获取key、value,设置value
  37. Set<Entry<String, Coordinate>> entries = rect.entrySet();
  38. Iterator<Entry<String, Coordinate>> it3 = entries.iterator();
  39. while(it3.hasNext()) {
  40. Entry<String, Coordinate> entry = it3.next();
  41. String key = entry.getKey();
  42. System.out.println(key);
  43. Coordinate value = entry.getValue();
  44. System.out.println(value);
  45. entry.setValue(new Coordinate("?", "?"));
  46. }
  47. System.out.println(rect);
  48. }
  49. }
  50.  
  51. /**
  52. * 坐标类
  53. *
  54. * @author forget406
  55. * @since 09/08/2016
  56. * @param <T> 泛型参数
  57. */
  58. class Coordinate<T> {
  59. private T x;
  60. private T y;
  61.  
  62. public Coordinate(T x, T y) {
  63. this.x = x;
  64. this.y = y;
  65. }
  66.  
  67. @Override
  68. public int hashCode() {
  69. final int prime = 31;
  70. int result = 1;
  71. result = prime * result + ((x == null) ? 0 : x.hashCode());
  72. result = prime * result + ((y == null) ? 0 : y.hashCode());
  73. return result;
  74. }
  75.  
  76. @SuppressWarnings("unchecked")
  77. @Override
  78. public boolean equals(Object obj) {
  79. if (this == obj)
  80. return true;
  81. if (obj == null)
  82. return false;
  83. if (getClass() != obj.getClass())
  84. return false;
  85. Coordinate<T> other = (Coordinate<T>) obj;
  86. if (x == null) {
  87. if (other.x != null)
  88. return false;
  89. } else if (!x.equals(other.x))
  90. return false;
  91. if (y == null) {
  92. if (other.y != null)
  93. return false;
  94. } else if (!y.equals(other.y))
  95. return false;
  96. return true;
  97. }
  98.  
  99. @Override
  100. public String toString() {
  101. return "(" + x + "," + y + ")";
  102. }
  103. }
  1. point C
  2. point B
  3. point A
  4. point D
  5. (1,1)
  6. (1,0)
  7. (0,0)
  8. (0,1)
  9. point C
  10. (1,1)
  11. point B
  12. (1,0)
  13. point A
  14. (0,0)
  15. point D
  16. (0,1)
  17. {point C=(?,?), point B=(?,?), point A=(?,?), point D=(?,?)}

程序运行结果

for-each实现

在JDK1.5版本引入for-each(由JVM维护,内部实现也是通过迭代器实现)后,上面那种有点原始社会的感觉。所以一般我都是使用for-each遍历Map

  1. import java.util.Collection;
  2. import java.util.HashMap;
  3. import java.util.Iterator;
  4. import java.util.Map;
  5. import java.util.Map.Entry;
  6. import java.util.Set;
  7.  
  8. public class MapStudy {
  9. @SuppressWarnings({ "unchecked", "rawtypes" })
  10. public static void main(String[] args) {
  11. Map<String, Coordinate> rect =
  12. new HashMap<String, Coordinate>();
  13. rect.put("point A", new Coordinate(0, 0));
  14. rect.put("point B", new Coordinate(1, 0));
  15. rect.put("point C", new Coordinate(1, 1));
  16. rect.put("point D", new Coordinate(0, 1));
  17.  
  18. /***** for-each方式遍历代码 *****/
  19. // 遍历key,获取key
  20. Set<String> keys = rect.keySet();
  21. for(String key : keys) {
  22. System.out.println(key);
  23. }
  24.  
  25. // 遍历value,获取value
  26. Collection<Coordinate> values = rect.values();
  27. for(Coordinate value : values) {
  28. System.out.println(value);
  29. }
  30.  
  31. // 遍历key-value对,获取key、value,设置value
  32. Set<Entry<String, Coordinate>> entries = rect.entrySet();
  33. for(Entry<String, Coordinate> entry : entries) {
  34. String key = entry.getKey();
  35. System.out.println(key);
  36. Coordinate value = entry.getValue();
  37. System.out.println(value);
  38. entry.setValue(new Coordinate("?", "?"));
  39. }
  40. System.out.println(rect);
  41. }
  42. }
  43.  
  44. /**
  45. * 坐标类
  46. *
  47. * @author forget406
  48. * @since 09/08/2016
  49. * @param <T> 泛型参数
  50. */
  51. class Coordinate<T> {
  52. private T x;
  53. private T y;
  54.  
  55. public Coordinate(T x, T y) {
  56. this.x = x;
  57. this.y = y;
  58. }
  59.  
  60. @Override
  61. public int hashCode() {
  62. final int prime = 31;
  63. int result = 1;
  64. result = prime * result + ((x == null) ? 0 : x.hashCode());
  65. result = prime * result + ((y == null) ? 0 : y.hashCode());
  66. return result;
  67. }
  68.  
  69. @SuppressWarnings("unchecked")
  70. @Override
  71. public boolean equals(Object obj) {
  72. if (this == obj)
  73. return true;
  74. if (obj == null)
  75. return false;
  76. if (getClass() != obj.getClass())
  77. return false;
  78. Coordinate<T> other = (Coordinate<T>) obj;
  79. if (x == null) {
  80. if (other.x != null)
  81. return false;
  82. } else if (!x.equals(other.x))
  83. return false;
  84. if (y == null) {
  85. if (other.y != null)
  86. return false;
  87. } else if (!y.equals(other.y))
  88. return false;
  89. return true;
  90. }
  91.  
  92. @Override
  93. public String toString() {
  94. return "(" + x + "," + y + ")";
  95. }
  96. }

Map体系结构

Map接口的实现类大致分为两大类:

通用映射表类

HashMap(散列映射表)、TreeMap(二叉树映射表)

专用映射表类

IdentityHashMap(标识散列映射表)、WeakHashMap(弱散列映射表)、LinkedHashMap(链接散列映射表)、EnumMap(枚举映射表)等。

当然,上面只是比较粗略地分类,后续文章将进一步深入分析Map相关接口、抽象类、实现类的内部机制,以及其于Set集的对应关系。

Map相关问题思考

思考1:标识符命名单复数

这个问题不光光是Map有,整个Java语言在设计时都是采用这种思路。这种写法归根结底还是由于英语国家语言语法习惯,值得我们在平时命名的时候注意。

  1. boolean containsKey(Object key);

如果换成我习惯的命名法则,让我来设计底层代码,可能就写成

  1. boolean containKey(Object key);
  2.  
  3. boolean isContainKey(Object key);

真的是一个大写的囧 o(╯□╰)o  和大牛的差距就体现出来了。

对于设计方法标识符时大致应该遵循:

1、如果方法用于判断,即返回值是boolean

  1. boolean isAbAb是名词) // 判断对象是Ab吗?
    boolean AbsCdAbs是动词单数,Cd是名词) // 判断对象Abs了Cd?比如上面的ContainsKey

2、一般的方法,规则是动词开头(具体判断是否加单数),后可以加名词或者连词(Of、As等)

思考2:Map视图

视图(views)其实是集合框架(collection frame)所共有的语言特性。

关于视图的内容,会单独整理总结成文,这里就是作为一块需要重点理解的内容提出来。

Map涉及到视图的内容:

  1. Set<K> keySet(); // 元素键视图集
  2. Collection<V> values(); // 元素值视图集
  3. Set<Map.Entry<K, V>> entrySet(); // 元素键/值对视图集
  1. /** Entry<K, V>接口,属于内部接口 */
    interface Entry<K,V> {
  2. K getKey(); // 获得键值对的键
  3. V getValue(); // 获得键值对的值
  4. V setValue(V value); // 设置键值对的值
  5. }  

思考3:Map遍历需要用Collection(集合)和Set(集)的原因分析

回头看前面Map接口源代码,你会发现它并没有写成

  1. public interface Map<K, V> extends Iterable<E>

而是简单地写成

  1. public interface Map<K, V>

也就是说,Map接口实际上是一个顶层接口。

相比较Collection<T>接口继承更顶层的Iterable<T>(拥有iterator()方法,以及for-each使用必须继承的接口),Map接口显得较为特殊。

为什么Map遍历必须借助Collection或Set呢?

假设现在Map接口源代码写成

  1. public interface Map<K, V> extends Iterable<E>

那么问题来了,该怎么遍历Map呢?现在有key、value两个泛型参数,当然我们可以将这两个泛型参数看成一对Entry,不过如果我需要单独遍历key或者value呢?无法单独通过Map实现。这就会显得功能太单调。

与其这样,不如一不做二不休,将Map<K, V>接口的遍历查询结果做成三种Set集或Collection集合视图。

Map<K, V>的K不能够重复,选择合适的数据结构Set储存。

Map<K, V>的V可以重复,选择合适的数据结构Collection储存。当然我个人认为List储存也是可以的,只不过设计者选择更加稳妥、保守的方式而已。

思考4:增删查改方法都有泛型返回值V(映射表值)

这一点其实也没琢磨太清楚,可能是设计者认为这么定义方法更加人性化。比如:

V remove(Object o) 删除映射表中指定键元素,如果删除则返回删除元素的值对象,反正则返回null。这样我们还能够看看到底删除值对不对。

自顶向下理解Java集合框架(三)Map接口的更多相关文章

  1. Java集合框架之Map接口浅析

    Java集合框架之Map接口浅析 一.Map接口综述: 1.1java.util.Map<k, v>简介 位于java.util包下的Map接口,是Java集合框架的重要成员,它是和Col ...

  2. Java集合框架中Map接口的使用

    在我们常用的Java集合框架接口中,除了前面说过的Collection接口以及他的根接口List接口和Set接口的使用,Map接口也是一个经常使用的接口,和Collection接口不同,Map接口并不 ...

  3. 【深入理解Java集合框架】红黑树讲解(上)

    来源:史上最清晰的红黑树讲解(上) - CarpenterLee 作者:CarpenterLee(转载已获得作者许可,如需转载请与原作者联系) 文中所有图片点击之后均可查看大图! 史上最清晰的红黑树讲 ...

  4. 第19章 集合框架(3)-Map接口

    第19章 集合框架(3)-Map接口 1.Map接口概述 Map是一种映射关系,那么什么是映射关系呢? 映射的数学解释 设A,B是两个非空集合,如果存在一个法则,使得对A中的每一个元素a,按法则f,在 ...

  5. Java集合框架之四大接口、常用实现类

    Java集合框架 <Java集合框架的四大接口> Collection:存储无序的.不唯一的数据:其下有List和Set两大接口. List:存储有序的.不唯一的数据: Set:存储无序的 ...

  6. Java集合框架之Set接口浅析

    Java集合框架之Set接口浅析 一.java.util.Set接口综述: 这里只对Set接口做一简单综述,其具体实现类的分析,朋友们可关注我后续的博文 1.1Set接口简介 java.util.se ...

  7. Java集合框架之List接口浅析

    Java集合框架之List接口浅析 一.List综述: 毫无疑问List接口位于java.util包下,继承自 Collection接口 存储元素的特点: 有序可重复(有序:即存进去是什么顺序,取出来 ...

  8. Java集合框架之Collection接口

    Java是一门面向对象的语言,那么我们写程序的时候最经常操作的便是对象了,为此,Java提供了一些专门用来处理对象的类库,这些类库的集合我们称之为集合框架.Java集合工具包位于Java.util包下 ...

  9. Java集合框架之map

    Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...

随机推荐

  1. Nginx01---简单使用

    基于腾讯云--ubuntu系统 1.安装nginx sudo apt-get install nginx 2.启动,停止nginx nginx -c /usr/local/nginx/conf/ngi ...

  2. 2019-5-1 maven学习笔记

    一.maven的好处 同样的项目使用maven工程来实现,由于不需要导入很多jar包,源码很小 原理:根据坐标到项目的仓库里查找需要的依赖 二.安装步骤 1.到http://maven.apache. ...

  3. CentOS7l联网

    原文:https://blog.csdn.net/nothing2017/article/details/61420767 步骤: 1.以root管理员身份登录系统,输入   --->(ls / ...

  4. docker容器时间不对及java程序时间不对解决

    使用docker容器部署的应用,会出现时间与主机不一致的情况 1. 容器时间与主机差8个小时:主机的与容器的/etc/localtime不一致 解决方法:挂载主机的/etc/localtime,如果没 ...

  5. Qt 学习之路 2(14):对话框数据传递

    Home / Qt 学习之路 2 / Qt 学习之路 2(14):对话框数据传递 Qt 学习之路 2(14):对话框数据传递  豆子  2012年9月15日  Qt 学习之路 2  53条评论 对话框 ...

  6. Android模拟器手动设置经纬度坐标

    第一种方式可以在eclipse的DDMS中的Emulator control中设置,如下图 另一种是在cmd中输入telnet localhost 5554(注:5554是模拟器在本机的端口,有可能不 ...

  7. Redis学习笔记(5)—— Redis的持久化方案&Redis的集群搭建

    一.Redis的持久化方案 Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化. Redis支持两种 ...

  8. 富文本编辑器...quill 的使用放...

    移动端 quill 时候用的 是 div 而不是 textarea.... 引入 dom <link href="//cdn.quilljs.com/1.3.6/quill.snow. ...

  9. angularJs(2)表单中下拉框单选多选

    多选 <input type="checkbox" ng-model='game' ng-true-value="1" ng-false-value=&q ...

  10. windows 7下安装MySQL5.6

    一. 软件下载 从MySql官网上下载响应的版本,我的是5.6.17. 二.安装过程 以管理员权限运行安装程序,收集信息. 选择安装MySql产品,如果之前有安装过,那么就选择更新了. 同意Licen ...