购物车的设计思想:一个商品对象,一个商品对象集合(这里使用HashMap).
购物车的功能:商品列表展示,点击查看详情(查看之后会被加入最近浏览的历时记录里),加入购物车,购物车商品展示(商品名称、数量、价格、以及最后的总价。)
在这里,不涉及 servlet,因为servlet就是处理业务逻辑代码,比如:点击商品查看详情,就是根据 商品ID查询商品,绑定到一个对象,再将对象绑定到对应作用域,比如request,session等,然后页面用标签取出来。
主要讲解,一个设计的思想,极其为什么这么设计。
购物车属性:商品总价格,HashMap<k,v> k:商品对象 v:购买的商品数量 这样设计,一个商品做为键,对应购买数量做为值。
1、首先有一个商品对象,记录商品信息,例如:商品ID,商品名称,价格,如下:
private String itemId;
private String itemName;
private Double price;
//getter/setter方法()
但是这个必须重写 Object 的两个方法:hashCode,equals 为什么?此次是为了防止重复的商品再次做为一个新商品加入购物车,正确的做法是,存在购物车的商品就应该在原有商品购买的数量上进行叠加。
代码重写如下:
/*@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.getId()+this.name.hashCode();
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if(this == obj){
return true;
}
if(obj instanceof Items){
Items i = (Items)obj;
if(this.getId() == i.getId() && this.getName() == i.getName()){
return true;
}else{
return false;
}
}else{
return false;
}
}*/
这里为什么要这么搞?文章结尾会做本质上的区别。
2、购物车对象
private HashMap<Items, Integer> goods;//K:商品对象,V:购买的数量
private Double totalPrice; //总价格
//getter/setter方法(略)
/**购物车操作方法**/
//增加商品
public boolean addGoodsInCart(Items item,Integer count){
if(goods.containsKey(item)){
goods.put(item, goods.get(item)+count);
}else{
goods.put(item, count);
}
callTotalPrice();//计算总价格
return true;
}
//删除商品
public boolean removeGoodsFromCart(Items item){
goods.remove(item);
callTotalPrice();
return true;
}
//计算总价格
public Double callTotalPrice(){
Double sum = 0.0;
Set<Items> keys = goods.keySet();
Iterator<Items> it = keys.iterator();
while(it.hasNext()){
Items item = it.next();
sum = sum + item.getPrice()*goods.get(item);
//System.err.println(item.getPrice()+"*"+goods.get(item)+"="+sum);
}
this.setTotalPrice(sum);
return this.getTotalPrice();
}
下面只提供,main方法,因为,如果要从页面操作的话,就关系到数据库或者说使用session来存储数据,比较繁杂,这里简洁的写法,这里提供main方法:
public static void main(String[] args) {
Items i1 = new Items(1,"足球",20.00);
Items i2 = new Items(2,"篮球",30.00);
Items i3 = new Items(1,"足球",40.00);
Cart c = new Cart();
c.addGoodsInCart(i1, 1);
c.addGoodsInCart(i2, 2);
c.addGoodsInCart(i3, 5);
Set<Map.Entry<Items, Integer>> items = c.getGoods().entrySet();
for (Map.Entry<Items, Integer> obj : items) {
Items item = obj.getKey();
Integer count = obj.getValue();
//System.out.println(obj.toString());
System.out.println("商品:"+item.getName()+",价格:"+item.getPrice()+"数量:"+count);
}
System.out.println("总共:"+c.getTotalPrice());
}
3、关于浏览过商品思路,存放在cookie.
根据查看详情收集 id,并且id之间用","分割,然后存放在cookie当中
<%
String list ="";
//从客户端获得Cookies集合
Cookie[] cookies = request.getCookies();
//遍历这个Cookies集合
if(cookies!=null&&cookies.length>0)
{
for(Cookie c:cookies)
{
if(c.getName().equals("ListViewCookie"))
{
list = c.getValue();
}
}
}
list+=request.getParameter("id")+",";
//如果浏览记录超过1000条,清零.
String[] arr = list.split(",");
if(arr!=null&&arr.length>0)
{
if(arr.length>=1000)
{
list="";
}
}
Cookie cookie = new Cookie("ListViewCookie",list);
response.addCookie(cookie);
%>
将cookid中存放的 list格式为:id1,id2,id3 这个格式字符串传到后台,后台通过封装成一个List<商品对象>,到页面即可展示出来。
扩展:
判断两个对象是否相等,为什么必须同时重写equals()和hashcode()方法<资料如下>
资料地址:http://blog.sina.com.cn/s/blog_5396eb5301013ugt.html
对象存在堆内存。
首先说建议的情况: 比如你的对象想放到Set集合或者是想作为Map的key时,那么你必须重写equals()方法,这样才能保证唯一性。当然,在这种情况下,你不想重写hashCode()方法,也没有错。但是,对于良好的编程风格而言,你应该在重写equals() 方法的同时,也重写hashCode()方法。
必须重写hashCode()的情况:
如果你的对象想放进散列存储的集合中(比如:HashSet,LinkedHashSet)或者想作为散列Map(例如:HashMap,LinkedHashMap等等)的Key时,在重写equals()方法的同时,必须重写hashCode()方法。
1.hashCode()方法存在的主要目的就是提高效率。
2.在集合中判断两个对象相等的条件,其实无论是往集合中存数据,还是从集合中取数据,包括如果控制唯一性等,都是用这个条件判断的,条件如下:
首先判断两个对象的hashCode是否相等,如果不相等,就认为这两个对象不相等,就完成了。如果相等,才会判断两个对象的equals()是否相等,如果不相等,就认为这两个对象不相等,如果相等,那就认为这两个对象相等。
最后总结一句话就是,hashCode()方法存在的主要目的就是提高效率,但是如果你想把对象放到散列存储结构的集合中时,是必须要重写的。
完毕!