哈希表(Hashtable)又称为“散置”,Hashtable是会根据索引键的哈希程序代码组织成的索引键(Key)和值(Value)配对的集合。Hashtable 对象是由包含集合中元素的哈希桶(Bucket)所组成的。而Bucket是Hashtable内元素的虚拟子群组,可以让大部分集合中的搜寻和获取工作更容易、更快速。
哈希函数(Hash Function)为根据索引某些属性值(Value)。当对象加入至Hashtable时,它存储在与对象哈希程序代码相符的哈希程序代码相关的Bucket键来返回数值哈希程序代码的算法。索引键(Key)是被存储对象的中。当在Hashtable内搜寻值时,哈希程序代码会为该值产生,并且会搜寻与该哈希程序代码相关的Bucket。例如,student和teacher会放在不同的Bucket中,而dog和god会放在相同的Bucket中。所以当索引键是唯一从Hashtable获取元素的性能时表现会较好。Hash的四大优点如下所示。
1、事先不需要排序。
2、搜寻速度与数据多少无关。
3、数字签名的密码技术保密性(Security)高。
4、可做数据压缩(Data Compression),以节省空间。
定义:
享元模式(Flyweight):运用共享的技术有效地支持大量细粒度的对象。提供了通过减少对象的数量,从而改善应用所需要的对象结构;运用共享技术有效的支持i大量细粒度的对象。
适用性
Flyweight模式的有效性很大程度上取决于如何使用它以及在何处使用它。当以下情况都成立时使用Flyweight模式。
1)一个应用程序使用了大量的对象。
2)完全由于使用大量的对象,造成很大的存储开销。
3)对象的大多数状态都可变为外部状态。
4)如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
5)应用程序不依赖对象标识。
总结:即常常用于系统底层开发,以便解决系统的性能问题;系统有大量的相似对象,需要缓冲池的场景。
缺点:
1)享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
2)享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
优点:
3)减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率;
4)减少内存之外的其他的资源占用。
案例:
第一部分为所有具体享元类的具体超类(员工类),通过这个接口,提供了公共实现方法。
public interface Employee {
public void report();
}
管理类为继承员工类的具体实现类,即具体的享元类;该manage类reportCount为外部状态,department 为内部状态;一般的外部状态为根据外部的提示可以识别一个享元类,即外部状态,需要外部赋值。
public class Manager implements Employee {
String department;//外部状态
String reportContent;//内部状态
public Manager(String reportContent) {
this.reportContent = reportContent;
}
public void setDepartment(String department) {
this.department = department;
}
//实现业务
public void report() {
System.out.println("reportContent:"+reportContent);
}
}
Factory为享元工厂,其目的是根据外部状态获得具体实现对象,如果没有则创建一个对象,也正是因为有这个工厂存在,工厂中的容器池管理多个对象,达到了对象复用,减少对象创建,减少内存占用的目的;
public class EmployeeFactory {
/*定义一个容器池*/
private final static Map<String,Employee> map = new HashMap<String, Employee>();
/*享元工厂*/
public static Employee getManager(String department){
Manager manager = (Manager) map.get(department);
/*容器池中没有该对象则根据外部状态创建*/
if(manager == null)
{
manager = new Manager(department);
manager.setDepartment("汇报人:"+department);
map.put(department,manager);
System.out.println("创建部门经理:"+department);
}
return manager;
}
}
客户端类
public class Test {
public static void main(String[] args) {
Employee employee1 = EmployeeFactory.getManager("qq");
employee1.report();
Employee employee2 = EmployeeFactory.getManager("ww");
employee2.report();
}
}