关闭

栈+哈希表(或者稀疏数组)解决安卓购物车新添加货物置顶的问题

标签: android购物车的实现哈希表稀疏数组SharedPreferences
1097人阅读 评论(0) 收藏 举报
分类:

最近在做仿淘宝购物的APP(目前已经完成,有时间就把这个项目写出来),在做购物车这一块的时候,我是把数据先转化为json数据,然后通过sharedpreferences来把数据保存到本地内存中(至少用户没有登录的情况下可以这么做),我们知道sharedpreferences是通过键值对来存储数据的(不清楚的同学请移步Android源代码分析之sharedpreferences),key值可以随便给定一个常量,取的时候也是需要通过这个key来取的,以下即是存储的代码:

public void commit(){
    List<ShoppingCart> carts = sparseToList();//ShoppingCart是对商品属性的一个封装类,sparseToList()下面会给出解释

    PreferencesUtils.putString(mContext,CART_JSON,JSONUtil.toJSON(carts));//JSONUtil是对json数据转换功能进行封装的一个类
}

在PreferencesUtils类里面封装了对sharedpreferences的调用:

public static boolean putString(Context context, String key, String value) {
        SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = settings.edit();
        editor.putString(key, value);
        return editor.commit();
    }

在最开始做的时候对于carts中商品的排序是根据商品的id来的,以下是spareseToList函数的代码:

private List<ShoppingCart> sparseToList(){


        int size = datas.size();//datas是存储商品的稀疏数组

        List<ShoppingCart> list = new ArrayList<>(size);
        for (int i=0;i<size;i++){

            list.add(datas.valueAt(i));
        }
        return list;

    }
上面这个函数的作用是把稀疏数组里面的元素添加到新建的List中,稀疏数组插入元素的时候是通过二分法来判断数组里面是否已经包含了这个key值,如果包含了,那么只需要修改这个key对应的value值即可,如果没有包含,那么需要将key和value添加到稀疏数组当中,源代码如下:
 public void put(int key, E value) {
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

        if (i >= 0) {
            mValues[i] = value;
        } else {
            i = ~i;

            if (i < mSize && mValues[i] == DELETED) {
                mKeys[i] = key;
                mValues[i] = value;
                return;
            }

            if (mGarbage && mSize >= mKeys.length) {
                gc();

                // Search again because indices may have changed.
                i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
            }

            mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
            mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
            mSize++;
        }
    }
其中二分查找的源代码如下:
static int binarySearch(int[] array, int size, int value) {
        int lo = 0;
        int hi = size - 1;

        while (lo <= hi) {
            final int mid = (lo + hi) >>> 1;
            final int midVal = array[mid];

            if (midVal < value) {
                lo = mid + 1;
            } else if (midVal > value) {
                hi = mid - 1;
            } else {
                return mid;  // value found
            }
        }
        return ~lo;  // value not present
    }
如果源代码有些地方看不懂,可以自己去搜一下稀疏数组。既然用到了二分法,那么稀疏数组里面的key值是从小到大有序排列的,所以回到前面所说的商品是以商品id为key值,商品cart为value,添加商品到购物车的代码如下:
public void put(ShoppingCart cart){


       ShoppingCart temp =  datas.get(cart.getId().intValue());//查询购物车里面是否已经有这一件商品了

        if(temp !=null){                                       //如果有的话那么只需要将数量+1
            temp.setCount(temp.getCount()+1);
        }
        else{                                                  //如果没有就添加到购物车
            temp = cart;
            temp.setCount(1);
        }

        datas.put(cart.getId().intValue(),temp);

        commit();//即上面第一段的commit代码

    }

这里以商品id来排序会造成一个比较糟糕的用户体验,即用户添加一件商品到购物车,然而购物车的第一件商品并不一定是刚刚用户添加的那件货物,当用户添加了很多件商品之后再添加其他的一件商品,可能这件商品会在用户的购物屏幕上“消失”,用户还得翻滚屏幕来寻找刚刚添加的那件商品。所以我们不能使用商品id来作为稀疏数组的key值,那该用商品的什么属性来作为key呢?用时间吗?听起来不错,不过这并不是商品的属性,那有没有更好的办法来使得先进来的商品最后才显示出来呢?对了,使用栈,可是使用java本身所具有的那个stack栈的话,如果要随机访问datas.get(cart.getId().intValue());里面的元素,那么对于栈来说效率太差了,那么我们可不可以存储和读取数据的时候使用栈,而随机访问当中的元素的时候就使用哈希表或者稀疏数组,我这里是使用了稀疏数组,至于为什么不用哈希表,大家可以参看稀疏数组相比于哈希表(HashMap/HashTable)的优点。所以添加商品到购物车的代码如下:

datas = new SparseArray<>(10);
shoppingDatas = new LinkedList<>();//这里使用LinkedList来取代stack使用,相比于stack来说前者效率更好
public void put(ShoppingCart cart){  


        ShoppingCart temp =  datas.get(cart.getId().intValue());//查询购物车里面是否已经有这一件商品了
        if(temp !=null){
            temp.setCount(temp.getCount() + 1);                 //因为商品个数是商品的属性,所以无论是栈还是数组里面的数据都会发生改变
        }
        else{
            temp = cart;
            temp.setCount(1);
            shoppingDatas.push(cart);                         //数据同时添加到栈里面和稀疏数组里面
        }

        datas.put(cart.getId().intValue(), temp);
        commit();

    }
数据存储到内存中的代码如下:
public void commit(){


        List<ShoppingCart> carts = sparseToList();

        PreferencesUtils.putString(mContext,CART_JSON,JSONUtil.toJSON(carts));

    }


    private List<ShoppingCart> sparseToList(){


        int size = shoppingDatas.size();

        System.out.println(size);
        List<ShoppingCart> list = new ArrayList<>(size);
        for (int i= 0;i<size;i++){
            list.add(shoppingDatas.get(i));      //将栈中的数据按照从栈顶到栈底的顺序添加到List中
        }
        return list;                            //将list返回作为json数据保存到SharedPreferences中

    }
从内存中读取出来的代码如下:
private void listToSparse(){

        List<ShoppingCart> carts =  getDataFromLocal();  //从SharedPreferences中取出json数据

        if(carts!=null && carts.size()>0){

            for (ShoppingCart cart: carts) {

                datas.put(cart.getId().intValue(), cart);  //将数据同时添加到栈以及稀疏数组中
                shoppingDatas.push(cart);
            }
        }

    }
public  List<ShoppingCart> getDataFromLocal(){

        String json = PreferencesUtils.getString(mContext,CART_JSON);
        System.out.println(json);
        List<ShoppingCart> carts =null;
        if(json !=null ){

            carts = JSONUtil.fromJson(json,new TypeToken<List<ShoppingCart>>(){}.getType());//读取json数据

        }

        return  carts;

    }
效果图如下所示:



0
0
查看评论

java常用的几种数据结构,堆栈,队列,数组,链表,哈希表

java常用的几种数据结构,堆栈,队列,数组,链表,哈希表
  • weixin_39800144
  • weixin_39800144
  • 2017-08-27 12:10
  • 331

开发购物车模块中遇到的问题

无法添加商品 需求:点击商品详细页面中的“我要购买”按钮,servlet获得请求,根据session中的uid和hidden的book id来搜索数据库,若找到记录,那么在原有的记录上添加商品数量;否则新增条目。 问题:商品没有添加,数量也没有增加 原因:问题出在Dao中的toCartItem(Ma...
  • Iswear_1992
  • Iswear_1992
  • 2015-10-19 15:07
  • 1317

Java数据结构-稀疏数组

稀疏数组就是数组中,大部分的元素值  都未被使用(或都为0),在数组中仅有少  部分的空间使用。因此造成内存空间的浪  费,为了解决这问题,并且不影响数组中原  有的元素值,我们采用了一种压缩的方式来  表示稀疏数组的内...
  • likaiwalkman
  • likaiwalkman
  • 2015-06-10 00:22
  • 761

android购物车遇到的问题

android购物车遇到的问题
  • ab601026460
  • ab601026460
  • 2014-07-05 01:10
  • 1683

括号匹配问题(不用栈,用数组)

不用模板栈的话,就是建立一个数组,输入若是左括号,则入栈,stack[++top]=a[i],top为栈顶元素的指针,若是右括号,则出栈,stack[top--]。 此处关键是自增符号的顺序,为什么入栈要先加,出栈后减,因为栈顶指针永远都是最后一个元素前一个位置,入栈的时候要先移动指针,到上一个,...
  • Scarlett_geng
  • Scarlett_geng
  • 2016-05-11 21:07
  • 1018

Android基础知识【项目实训-添加购物车】【8】

当用户点击某一个 餐品时,会打开详细介绍界面,并可以确定购买数量,点击“预订”按钮就可以加入购物车。购物车中的每一项都对应 将来生成订单的
  • freeman527
  • freeman527
  • 2014-12-26 14:46
  • 22125

参数设置,取消flash置顶!

  • mijingai
  • mijingai
  • 2009-11-16 12:55
  • 2406

稀疏数组详解

什么是稀疏数组     数组元素的索引不一定要连续的,它们之间可以有空缺。每个javaScript数组都有一个length属性。针对非稀疏数组,该属性就是数组元素的个数;针对稀疏数组,length比所有元素的个数要大。 创建稀疏数组 用构造函数创建 var a=new Array...
  • u013692413
  • u013692413
  • 2014-02-19 10:08
  • 2043

android实现简单的购物车

一.布局:item_shopcart_group.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.andro...
  • c_bulrush
  • c_bulrush
  • 2017-10-25 19:17
  • 256

javascript中的稀疏数组(sparse array)和密集数组

学习underscore.js数组相关API的时候,遇到了sparse array这个东西,以前没有接触过。这里学习下什么是稀疏数组和密集数组。JavaScript中的数组并不像我们在C或java等语言中遇到的常规数组,在js中数组并不是起始地址+长度构成的一片连续的地址空间。
  • aitangyong
  • aitangyong
  • 2014-10-17 21:52
  • 3443
    个人资料
    • 访问:63121次
    • 积分:843
    • 等级:
    • 排名:千里之外
    • 原创:34篇
    • 转载:16篇
    • 译文:0篇
    • 评论:12条
    文章分类
    最新评论