- 浏览: 340552 次
- 性别:
- 来自: 重庆
文章分类
最新评论
-
hjl0722:
...
Java中的异或 -
lucd:
f(New.<Person, List<Pet&g ...
第15章泛型 -
liujunhao225:
[Error: could not access: List; ...
mvel的使用 -
superscorpio:
public void testImportInContex ...
mvel的使用 -
yuyangtina:
哦,知道了,是继承的方法。谢谢你的分享。
HttpClient3.x发送Soap请求的方法
1.List接口的相关方法
1)toArray
Object[] toArray()
Returns an array containing all of the elements in this list in proper sequence. Obeys the
general contract of the Collection.toArray method.
2)toArray
<T> T[] toArray(T[] a)
Returns an array containing all of the elements in this list in proper sequence; the runtime
type of the returned array is that of the specified array. Obeys the general contract of the
Collection.toArray(Object[]) method.
Parameters:
a - the array into which the elements of this list are to be stored, if it is big enough;
otherwise, a new array of the same runtime type is allocated for this purpose.
Returns:
an array containing the elements of this list.
3)set
E set(int index,
E element)
Replaces the element at the specified position in this list with the specified element
(optional operation).
Parameters:
index - index of element to replace.
element - element to be stored at the specified position.
Returns:
the element previously at the specified position.
4)clear
void clear()
Removes all of the elements from this list (optional operation). This list will be empty after
this call returns (unless it throws an exception).
5)removeAll
boolean removeAll(Collection<?> c)
Removes from this list all the elements that are contained in the specified collection
(optional operation).
Parameters:
c - collection that defines which elements will be removed from this list.
Returns:
true if this list changed as a result of the call.
2.HashSet为快速查找而设计的Set,存入HashSet的元素必须定义hashCode()
TreeSet保持次序的Set,底层为树结构,必须实现Comparable接口
LinkedHashSet,具有HashSet的查询速度,且内部维护元素的出入次序。
3.Map的实现
public class AssociativeArray<K, V> {
private Object[][] pairs;
private int index;
public AssociativeArray(int length) {
pairs = new Object[length][2];
}
public void put(K key, V value) {
if (index >= pairs.length)
throw new ArrayIndexOutOfBoundsException();
pairs[index++] = new Object[] { key, value };
}
@SuppressWarnings("unchecked")
public V get(K key) {
for (int i = 0; i < index; i++)
if (key.equals(pairs[i][0]))
return (V) pairs[i][1];
return null; // Did not find key
}
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < index; i++) {
result.append(pairs[i][0].toString());
result.append(" : ");
result.append(pairs[i][1].toString());
if (i < index - 1)
result.append("\n");
}
return result.toString();
}
public static void main(String[] args) {
AssociativeArray<String, String> map = new AssociativeArray<String, String>(
6);
map.put("sky", "blue");
map.put("grass", "green");
map.put("ocean", "dancing");
map.put("tree", "tall");
map.put("earth", "brown");
map.put("sun", "warm");
try {
map.put("extra", "object"); // Past the end
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Too many objects!");
}
System.out.println(map);
System.out.println(map.get("ocean"));
}
}
上面的代码只是说明性的,而且大小还固定,要和真正的Map比起来效率差很多。
4.散列码与散列
Object的hashCode()方法生成的散列码,默认是根据对象的地址计算出的散列码。即,如果一个类不重写该方法
,那么由该类生成的不同对象的散列码是不同的。
Object的equals()方法默认比较的是对象的地址。且正确的equals方法必须满足5个条件
1)自反行。对任意x,x.equals(x)一定返回true
2)对称性。对任意的x.equals(y)那么y.equals(x)也成立
3)传递性。x.equals(y),y.equals(z),x.equals(z)
4)一致性。如果返回true,那么不管调用任意多次都返回true
5)对任何不是null的x,x.equals(null)一定返回false.
如果要使用自己创建的类作为Map的键,必须同时覆盖equals和hashCode方法。
5.线性查询方式是最忙的查询方式。
6.区别
1)、equals方法用于比较对象的内容是否相等(覆盖以后)
2)、hashcode方法只有在集合中用到
3)、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)。
4)、将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入
总结:同一个类不同对象的散列码可能相同,可能不同,相同对象的散列码一定相同
7.通过key对象生成一个数字,将其作为数组的下标,这个数字就是散列码。该散列码由hashCode方法自动生成。为了解决数组容量被固定的问题,不同的键对象可以生成相同的散列码,这样数组大小就不是问题了。如果散列码有冲突,再用线性方式比较,因为经过散列后,相同散列码上的线性序列已经很小了,这比一开始就用线性搜索要快的多,这就是HashMap速度快的原因。
public class SimpleHashMap<K, V> extends AbstractMap<K, V> {
// Choose a prime number for the hash table
// size, to achieve a uniform distribution:
static final int SIZE = 997;
// You can't have a physical array of generics,
// but you can upcast to one:
@SuppressWarnings("unchecked")
LinkedList<MapEntry<K, V>>[] buckets = new LinkedList[SIZE];
public V put(K key, V value) {
V oldValue = null;
int index = Math.abs(key.hashCode()) % SIZE;
if (buckets[index] == null)
buckets[index] = new LinkedList<MapEntry<K, V>>();
LinkedList<MapEntry<K, V>> bucket = buckets[index];
MapEntry<K, V> pair = new MapEntry<K, V>(key, value);
boolean found = false;
ListIterator<MapEntry<K, V>> it = bucket.listIterator();
while (it.hasNext()) {
MapEntry<K, V> iPair = it.next();
if (iPair.getKey().equals(key)) {
oldValue = iPair.getValue();
it.set(pair); // Replace old with new
found = true;
break;
}
}
if (!found)
buckets[index].add(pair);
return oldValue;
}
public V get(Object key) {
int index = Math.abs(key.hashCode()) % SIZE;
if (buckets[index] == null)
return null;
for (MapEntry<K, V> iPair : buckets[index])
if (iPair.getKey().equals(key))
return iPair.getValue();
return null;
}
public Set<Map.Entry<K, V>> entrySet() {
Set<Map.Entry<K, V>> set = new HashSet<Map.Entry<K, V>>();
for (LinkedList<MapEntry<K, V>> bucket : buckets) {
if (bucket == null)
continue;
for (MapEntry<K, V> mpair : bucket)
set.add(mpair);
}
return set;
}
public static void main(String[] args) {
SimpleHashMap<String, String> m = new SimpleHashMap<String, String>();
m.putAll(Countries.capitals(25));
System.out.println(m);
System.out.println(m.get("ERITREA"));
System.out.println(m.entrySet());
}
}
8.由散列码组成的表称为散列表,每个散列码称为“槽为”或是“桶位”;
9.对于现代的处理器而言,除法和求余数是最慢的操作。java的散列函数都使用2的整数次方。
10.如果想让对象生成的散列码在某个范围内,比如在0到5直接,那么就在原来的散列码基础上对5求余数。
11.在设计Hashcode方法时,最重要的就是同一个对象生成的散列码应该相同,否则在get的时候就无法取到该值。因此,散列码得生成不能依赖易变的数组或者是唯一性的数据。
12.hashCode方法的编写规则
1)生成散列码得速度必须快,并且有意义(即必须基于对象内容生成散列码);
2)散列码不必是独一无二的(重点关注速度,而不是唯一性);
3)散列码分布必须均匀;
怎么样编写hashCode方法,Joshua Block给出了一个基本的指导
1)给int变量result赋值非零常量,例如17;
2)给对象内每个有意义的域f,计算出一个int散列码c;
3)把计算得出的散列码合并;
例如:
public class CountedString {
private static List<String> created = new ArrayList<String>();
private String s;
private int id = 0;
public CountedString(String str) {
s = str;
created.add(s);
// id is the total number of instances
// of this string in use by CountedString:
for (String s2 : created)
if (s2.equals(s))
id++;
}
public String toString() {
return "String: " + s + " id: " + id + " hashCode(): " + hashCode();
}
public int hashCode() {
// The very simple approach:
// return s.hashCode() * id;
// Using Joshua Bloch's recipe:
int result = 17;
result = 37 * result + s.hashCode();
result = 37 * result + id;
return result;
}
}
依照上面的指导原则,大致可以生成一个均匀分布的散列码
1)toArray
Object[] toArray()
Returns an array containing all of the elements in this list in proper sequence. Obeys the
general contract of the Collection.toArray method.
2)toArray
<T> T[] toArray(T[] a)
Returns an array containing all of the elements in this list in proper sequence; the runtime
type of the returned array is that of the specified array. Obeys the general contract of the
Collection.toArray(Object[]) method.
Parameters:
a - the array into which the elements of this list are to be stored, if it is big enough;
otherwise, a new array of the same runtime type is allocated for this purpose.
Returns:
an array containing the elements of this list.
3)set
E set(int index,
E element)
Replaces the element at the specified position in this list with the specified element
(optional operation).
Parameters:
index - index of element to replace.
element - element to be stored at the specified position.
Returns:
the element previously at the specified position.
4)clear
void clear()
Removes all of the elements from this list (optional operation). This list will be empty after
this call returns (unless it throws an exception).
5)removeAll
boolean removeAll(Collection<?> c)
Removes from this list all the elements that are contained in the specified collection
(optional operation).
Parameters:
c - collection that defines which elements will be removed from this list.
Returns:
true if this list changed as a result of the call.
2.HashSet为快速查找而设计的Set,存入HashSet的元素必须定义hashCode()
TreeSet保持次序的Set,底层为树结构,必须实现Comparable接口
LinkedHashSet,具有HashSet的查询速度,且内部维护元素的出入次序。
3.Map的实现
public class AssociativeArray<K, V> {
private Object[][] pairs;
private int index;
public AssociativeArray(int length) {
pairs = new Object[length][2];
}
public void put(K key, V value) {
if (index >= pairs.length)
throw new ArrayIndexOutOfBoundsException();
pairs[index++] = new Object[] { key, value };
}
@SuppressWarnings("unchecked")
public V get(K key) {
for (int i = 0; i < index; i++)
if (key.equals(pairs[i][0]))
return (V) pairs[i][1];
return null; // Did not find key
}
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < index; i++) {
result.append(pairs[i][0].toString());
result.append(" : ");
result.append(pairs[i][1].toString());
if (i < index - 1)
result.append("\n");
}
return result.toString();
}
public static void main(String[] args) {
AssociativeArray<String, String> map = new AssociativeArray<String, String>(
6);
map.put("sky", "blue");
map.put("grass", "green");
map.put("ocean", "dancing");
map.put("tree", "tall");
map.put("earth", "brown");
map.put("sun", "warm");
try {
map.put("extra", "object"); // Past the end
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Too many objects!");
}
System.out.println(map);
System.out.println(map.get("ocean"));
}
}
上面的代码只是说明性的,而且大小还固定,要和真正的Map比起来效率差很多。
4.散列码与散列
Object的hashCode()方法生成的散列码,默认是根据对象的地址计算出的散列码。即,如果一个类不重写该方法
,那么由该类生成的不同对象的散列码是不同的。
Object的equals()方法默认比较的是对象的地址。且正确的equals方法必须满足5个条件
1)自反行。对任意x,x.equals(x)一定返回true
2)对称性。对任意的x.equals(y)那么y.equals(x)也成立
3)传递性。x.equals(y),y.equals(z),x.equals(z)
4)一致性。如果返回true,那么不管调用任意多次都返回true
5)对任何不是null的x,x.equals(null)一定返回false.
如果要使用自己创建的类作为Map的键,必须同时覆盖equals和hashCode方法。
5.线性查询方式是最忙的查询方式。
6.区别
1)、equals方法用于比较对象的内容是否相等(覆盖以后)
2)、hashcode方法只有在集合中用到
3)、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)。
4)、将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入
总结:同一个类不同对象的散列码可能相同,可能不同,相同对象的散列码一定相同
7.通过key对象生成一个数字,将其作为数组的下标,这个数字就是散列码。该散列码由hashCode方法自动生成。为了解决数组容量被固定的问题,不同的键对象可以生成相同的散列码,这样数组大小就不是问题了。如果散列码有冲突,再用线性方式比较,因为经过散列后,相同散列码上的线性序列已经很小了,这比一开始就用线性搜索要快的多,这就是HashMap速度快的原因。
public class SimpleHashMap<K, V> extends AbstractMap<K, V> {
// Choose a prime number for the hash table
// size, to achieve a uniform distribution:
static final int SIZE = 997;
// You can't have a physical array of generics,
// but you can upcast to one:
@SuppressWarnings("unchecked")
LinkedList<MapEntry<K, V>>[] buckets = new LinkedList[SIZE];
public V put(K key, V value) {
V oldValue = null;
int index = Math.abs(key.hashCode()) % SIZE;
if (buckets[index] == null)
buckets[index] = new LinkedList<MapEntry<K, V>>();
LinkedList<MapEntry<K, V>> bucket = buckets[index];
MapEntry<K, V> pair = new MapEntry<K, V>(key, value);
boolean found = false;
ListIterator<MapEntry<K, V>> it = bucket.listIterator();
while (it.hasNext()) {
MapEntry<K, V> iPair = it.next();
if (iPair.getKey().equals(key)) {
oldValue = iPair.getValue();
it.set(pair); // Replace old with new
found = true;
break;
}
}
if (!found)
buckets[index].add(pair);
return oldValue;
}
public V get(Object key) {
int index = Math.abs(key.hashCode()) % SIZE;
if (buckets[index] == null)
return null;
for (MapEntry<K, V> iPair : buckets[index])
if (iPair.getKey().equals(key))
return iPair.getValue();
return null;
}
public Set<Map.Entry<K, V>> entrySet() {
Set<Map.Entry<K, V>> set = new HashSet<Map.Entry<K, V>>();
for (LinkedList<MapEntry<K, V>> bucket : buckets) {
if (bucket == null)
continue;
for (MapEntry<K, V> mpair : bucket)
set.add(mpair);
}
return set;
}
public static void main(String[] args) {
SimpleHashMap<String, String> m = new SimpleHashMap<String, String>();
m.putAll(Countries.capitals(25));
System.out.println(m);
System.out.println(m.get("ERITREA"));
System.out.println(m.entrySet());
}
}
8.由散列码组成的表称为散列表,每个散列码称为“槽为”或是“桶位”;
9.对于现代的处理器而言,除法和求余数是最慢的操作。java的散列函数都使用2的整数次方。
10.如果想让对象生成的散列码在某个范围内,比如在0到5直接,那么就在原来的散列码基础上对5求余数。
11.在设计Hashcode方法时,最重要的就是同一个对象生成的散列码应该相同,否则在get的时候就无法取到该值。因此,散列码得生成不能依赖易变的数组或者是唯一性的数据。
12.hashCode方法的编写规则
1)生成散列码得速度必须快,并且有意义(即必须基于对象内容生成散列码);
2)散列码不必是独一无二的(重点关注速度,而不是唯一性);
3)散列码分布必须均匀;
怎么样编写hashCode方法,Joshua Block给出了一个基本的指导
1)给int变量result赋值非零常量,例如17;
2)给对象内每个有意义的域f,计算出一个int散列码c;
3)把计算得出的散列码合并;
例如:
public class CountedString {
private static List<String> created = new ArrayList<String>();
private String s;
private int id = 0;
public CountedString(String str) {
s = str;
created.add(s);
// id is the total number of instances
// of this string in use by CountedString:
for (String s2 : created)
if (s2.equals(s))
id++;
}
public String toString() {
return "String: " + s + " id: " + id + " hashCode(): " + hashCode();
}
public int hashCode() {
// The very simple approach:
// return s.hashCode() * id;
// Using Joshua Bloch's recipe:
int result = 17;
result = 37 * result + s.hashCode();
result = 37 * result + id;
return result;
}
}
依照上面的指导原则,大致可以生成一个均匀分布的散列码
发表评论
-
final变量
2012-07-07 10:47 868final变量必须被初始化,不管是静态的还是非静态的,初始化的 ... -
第10章内部类
2012-07-05 00:40 838一、概述 package com.test; ... -
第12章 异常处理
2012-05-22 13:03 8511.Throwable类是所有异常类的基类,Throwable ... -
线程类中的同步关键字
2012-03-19 17:28 1231public class Constants { publ ... -
第20章注解
2012-03-03 11:32 8641.注解也被称为元数据 ... -
使用Executor
2012-02-29 17:24 1394相关代码: public class CachedThread ... -
死锁的问题
2012-02-29 15:35 9211.某个任务在等待另个任务,而后者有等待别的任务,这样一直下去 ... -
生产者消费者
2012-02-29 11:39 5261. class Meal { private final ... -
第21章 并发
2012-02-22 17:39 9661.基本上所有的并非模式在解决线程冲突问题时,都是采用序列化访 ... -
对象序列化
2012-02-06 17:49 1206当你创建对象时,只要你需要,它就会一直存在,但是在程序终止时, ... -
JAVA IO结构图
2012-02-05 16:00 1270图1 http://blog.sina.com.cn/s/b ... -
第18章IO系统
2012-02-03 18:11 9971. File类既能代表一个文件,也能代表某个目录下文件和子 ... -
第11章持有对象
2012-02-01 17:52 10581.向上转型也可作用于泛型(当指定了某个确切类型作为类型参数时 ... -
随机数
2012-01-31 10:23 1259java.util.Random类 1.public Ran ... -
第15章泛型
2012-01-30 17:25 20101.泛型,就是“适用于 ... -
第16章数组
2012-01-29 17:56 9351.数组和其他容器相比是一种效率最高的存储和随机访问对象的方式 ... -
第14章类型信息
2012-01-16 15:27 8371.类是程序的一部分, ... -
第13章 字符串操作
2011-12-14 23:43 9691. public class Concatenation { ... -
Interrupt
2010-11-01 20:36 981interrupt()只是改变中断状态而已 inte ... -
volatile
2010-10-09 09:08 1091以前就看到过Volatile关键字, 只知道跟多线程同步有关, ...
相关推荐
在深入研究Java集合框架,特别是List、Set和Queue的性能测试时,我们通常会关注它们在单线程环境中的表现...通过深入研究源码和构建测试框架,我们可以根据具体需求选择最高效的容器类型,从而优化我们的Java应用程序。
由于上传文件大小限制该资源为上下篇 本资源为下篇 第1章 对象导论 1.1 抽象过程 1.2 每个对象都有一个...第17章 容器深入研究 第18章 Java I/O系统 第19章 枚举类型 第20章 注解 第21章 并发 第22章 图形化用户界面
类型信息 第15章 泛型 第16章 数组 第17章 容器深入研究 第18章 Java I/O系统 第19章 枚举类型 第20章 注解 第21章 并发 第22章 图形化用户界面 附录A 补充材料 可下载的补充材料 Thinking in C:Java的基础 Java...
#### 第 17 章 容器深入研究 第十七章深入探讨了Java集合框架。本章详细讲解了Collection接口、List接口、Set接口以及Map接口的使用方法。此外,还会介绍ArrayList、LinkedList、HashSet、TreeSet、HashMap、...
think in java 源码 Java编程思想(第四版) ...容器深入研究 第18章 Java I/O系统 第19章 枚举类型 第20章 注解 第21章 并发 第22章 图形化用户界面 水平有限,发现错误不适者,出门左拐找童主任。
不久:• 17%不到一分钟• 78%不到一个小时• 89%不到一天• 95%不到一周最大的一类--27%,是在 5 到 10 分钟之间消失的容器。 本报告对 Docker 容器平台的应用进行了深入分析,揭示了五个有助于正确看待容器...
### 第十七章 标准模板库容器 更深入地研究了STL容器的高级特性,如迭代器适配器,容器适配器(如`stack`、`queue`、`priority_queue`)。 ### 第十八章 额外主题 涵盖了异常处理、命名空间、模板元编程、以及C++11...
031504_【第15章:Java反射机制】_Java反射机制的深入研究笔记.pdf 031505_【第15章:Java反射机制】_动态代理笔记.pdf 031506_【第15章:Java反射机制】_工厂设计模式笔记.pdf 031601_【第16章:Annotation】_系统...
11. **Java集合框架**:第十一章会深入研究Java集合框架的高级话题,如泛型,集合的排序,以及并发容器(如ConcurrentHashMap)。 12. **Java高级特性**:最后一章可能会讨论Java的新特性和更新,例如Java 8中的...
第十七章至第十九章:介绍了标准库,包括输入/输出流、字符串类、容器(如vector、list、set、map)、算法和迭代器等,这些都是C++程序员必备的知识。 第二十章至第二十一章:讨论了高级主题,如内存管理(包括指针...
第17章 异常处理 17.1 异常及其特性 17.2 异常处理的基本语法 17.3 异常的处理过程 17.4 抛出enum实例作为异常对象 17.5 抛出类所定义的对象 17.6 常犯的错误 17.7 本章重点 17.8 本章练习 PARTⅢ 面向对象...
#### 第17章 图形用户界面(GUI) - **组件设计**:按钮、文本框、滑块等。 - **事件响应**:用户交互行为的处理。 - **布局管理**:组件的排列方式。 #### 第18章 MATLAB 文件IO操作 - **文件读写**:读取和保存...
【WEB服务器工作机制由浅至深(9):【How Tomcat Works】第16章 关闭钩子以及之后的章节简述】 ...通过深入研究这些章节,开发者能够更好地理解Tomcat的内部运作,从而实现更高效、更可靠的Web服务部署。
#### 第17章:容器深入研究 - **容器框架**:探讨了 Java 集合框架中各种容器的特性和使用方法。 #### 第18章:Java I/O系统 - **输入输出流**:介绍了 Java 的 I/O 流处理技术,包括文件读写、网络通信等内容。 ...
### 第17章:错误和事件处理 错误处理是任何数据集成解决方案的重要组成部分。本章介绍了SSIS中的错误处理机制,并提供了实用的技巧来确保SSIS包能够正确地处理异常情况。 ### 第18章:编程和扩展SSIS 除了使用SSIS...
通过深入研究这些案例,你不仅可以巩固C++的基础知识,还能掌握如何将理论应用于实践,提升你的编程技巧和解决问题的能力。记得,实践是检验真理的唯一标准,通过亲手编写、运行和调试代码,你将在C++的世界里走得更...
##### 第17章:对话框与控件的运用(第985页) 介绍了对话框窗体的设计以及各种常用控件(按钮、文本框、列表框等)的使用方法。 ##### 第18章:文档存储与打印(第1047页) 讲解了如何保存和加载文件中的数据,...
最后,第十三章介绍了肉类罐头加工工艺,包括罐头容器的选择、基本工艺流程,以及具体罐头产品的加工实例。 教材和参考书的选择对于深入学习至关重要。《肉品工艺学》由孔保华主编,黑龙江科技出版社出版,作为主要...