栈+哈希表(或者稀疏数组)解决安卓购物车新添加货物置顶的问题
来源:互联网 发布:妖气漫画网软件 编辑:程序博客网 时间:2024/05/20 05:11
最近在做仿淘宝购物的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; }效果图如下所示:
- 栈+哈希表(或者稀疏数组)解决安卓购物车新添加货物置顶的问题
- 安卓购物车添加商品动画效果
- redis解决购物车的问题
- redis解决购物车的问题
- 安卓-购物车的实现
- 解决安卓style文件中设置Activity退出动画无效或者被干扰的问题
- 解决安卓windowAnimationStyle 设置退出动画无效或者被干扰的问题
- 多语言网店的产品详细页面跳转到购物车页面出现产品添加到购物车失败的问题的解决!!
- [Maven]添加新仓库或者新发布依赖后却获取不到问题的解决方案
- 安卓 购物车 单选反选
- 解决安卓添加Theme.NoTitleBar报错问题
- 解决“新添加的元素,事件不可用”的问题
- HTML 购物车计算总价+添加或者减少商品数量
- 解决稀疏矩阵问题
- ubuntu新添加用户无法sudo问题的解决
- Ubuntu新添加用户无法sudo问题的解决
- [置顶]新的博客
- 解决JAVA创建好的数组里添加新数据(忽略数组长度)
- linux 系统的 ctags 以及Makefile的应用
- 字典
- python语言磁力搜索引擎源码公开,基于DHT协议
- 数据库查询语句专题
- DP算法---最长公共子序列
- 栈+哈希表(或者稀疏数组)解决安卓购物车新添加货物置顶的问题
- SICP 练习1.16
- Spring 之注解事务 @Transactional propagation属性详解
- How to use HttpURLConnection POST data to web server?
- 使用UIDatePicker来选取日期和时间
- 【框架】App运行过程解析
- QT程序在其他机器连接不上数据库解决办法
- 第13周项目4-立体类族共有的抽象类
- SDUT_师创杯”山东理工大学第八届ACM程序设计竞赛部分题解