2015-08-01 10:46:40 u011411195 阅读数 455
  • Python入门视频教程

    购买课程后,请扫码进入学习群,获取唐宇迪老师答疑 Python入门基础教程:python教程旨在掌握python开发的入门基础用法与其核心操作,便于大家在短时间内可以使用python进行后续的工作与学习。课程内容包括Python环境搭建(Anaconda方式)、变量、List基础结构、List索引、循环结构、判断结构、字典结构、文件处理、函数基础等。

    18161 人正在学习 去看看 唐宇迪

这几天在学习数据结构(C++描述)的知识,为了把基础打的牢固一些,想想把一种数据结构自己动手写代码实现以下,感觉是个不错的方法。那样就不会只停留在会用的程度。首先整理一下要实现的山寨list要提供的接口。

push_back() 末端插入元素

back() 返回末端元素的值

push_front() 顶端插入元素

front() 返回顶端元素的值

find() 查找特定元素的地址

insert() 特定的位置插入元素

size() 返回list当中元素的个数

begin() 返回一个游标,指向顶端元素

end() 返回一个游标,指向末端元素

实现山寨list,底层的数据结构肯定选双向链表,在任何位置插入元素的复杂度都为o(1),双向链表是由一个个节点链接起来的,节点包括三个成员:指向后继节点的指针、指向前驱节点的指针、当前节点的节点值。先实现这个类:

template <typename T>
class dnode{
public:
	T nodeValue;//节点值
	dnode<T> *next;//后继节点
	dnode<T> *prev;//前驱节点
	dnode(const T& value=T()){
		nodeValue=value;
		next=NULL;
		prev=NULL;
	};//构造函数,初始化节点值、前驱和后继节点
};

然后将一个个节点串接起来就形成了双向链表,将双向链表的首位相接,就得到一个list,就像用一个个珠子串起来串成项链一样。实现miniList这个类:

#include "dnode.h"
#include <string>
using namespace std;
template <typename T>
class miniList{
public:
	miniList();/*三个版本的构造函数
	/第一个生成一个空list,第二个初始化list为n个item值的list
	第三个用[first,last]初始化list*/
	miniList(int n,const T& item=T());
	miniList(T *first,T *last);
	~miniList();//析构函数
	/*游标的声明*/
	class iterator{
		public:
			iterator();//构造函数,生成一个空游标
			iterator(dnode<T> *p);//构造函数,将dnode类型的指针转换为游标
			/*重载"=="和"!="运算符,比较两个游标所指的值*/
			bool operator ==(const iterator& rhs) const;
			bool operator !=(const iterator& rhs) const;
			/*重载"*"运算符,返回游标所指的值*/
			T& operator *();
			/*重载"++"和"--"运算符,因为这两个运算符有前缀和后缀的形式,所以后缀运算符多加一个
			int参数,好让编译器判断用户使用的是哪种形式。游标的本质其实还是指针,所以++或者--
			只是让私有成员node成为自身的后继或者前驱*/
			iterator& operator ++(){
				node=node->next;
				return *this;
			};
			iterator& operator ++(int){
				iterator temp=*this;
				node=node->next;
				return temp;
			};
			iterator& operator --(){
				node=node->prev;
				return *this;
			};
			iterator& operator --(int){
				iterator temp=*this;
				node=node->prev;
				return temp;
			};
		private:
			//游标的本质还是指针,指针的类型就是实现list的基石--dnode
			dnode<T> *node;
	};	
	void push_back(const T& item);//在list末端插入值
	T& back();//返回list末端的值
	void push_front(const T& item);//在list顶端插入值
	T& front();//返回list顶端的值
	/*在固定的位置插入值,返回新的新节点的地址,因为dnode指针是对外不可见的,所以要和find函数搭配使用*/
	dnode<T>* insert(const T& item,dnode<T> *curr);
	dnode<T>* find(const T& item);//查找一个元素的位置,返回这个元素的指针
	int size();//返回当前list的元素个数
	typename miniList<T>::iterator begin();//返回一个游标对象,指向list的顶端值
	typename miniList<T>::iterator end();//返回一个游标对象,指向list的末端值
private:
	dnode<T> *header;//头结点
	int listSize;//元素个数
};
template <typename T>//构造函数,生成一个空list,元素个数为0
miniList<T>::miniList(){
	header=new dnode<T>;
	listSize=0;
}
template <typename T>//构造函数,生个n个item元素的list
miniList<T>::miniList(int n,const T& item=T()){
	header=new dnode<T>(item);
	dnode<T> *temp;//存储n个item值的动态节点
	dnode<T> *curr;//当前节点
	curr=header;
	unsigned int i;
	for(i=0;i<n;i++){
		temp=new dnode<T>(item);//生成一个节点
		curr->next=temp;//当前节点的后继节点就是这个新生成的节点
		temp->prev=curr;//新节点的前驱节点为当前节点
		curr=temp;//更新当前节点,继续生成下一个节点
	}
	curr->next=header;//结束之后将当前节点的后继节点更新为头结点
	header->prev=curr;//头结点的前驱节点为当前这个节点,这样整个list就串起来
	listSize=n;//元素个数更新为n
}
template <typename T>
miniList<T>::miniList(T *first,T *last){
	/*先计算出first到last这段地址的元素数,其他的与上面类似,
	区别只是生成新节点时的节点值为当前地址中保存的值*/
	int n=last-first;
	header=new dnode<T>;
	dnode<T> *temp;
	dnode<T> *curr;
	curr=header;
	unsigned int i;
	for(i=0;i<n;i++){
		temp=new dnode<T>(*first);
		curr->next=temp;
		temp->prev=curr;
		curr=temp;
		first++;
	}
	curr->next=header;
	header->prev=curr;
	listSize=n;
}
template <typename T>//析构函数,遍历整个list,逐个释放内存
miniList<T>::~miniList(){
	dnode<T> *curr;
	curr=header->next;
	while(curr!=header){
		delete curr;
		curr=curr->next;
	}
	delete header;
}
template <typename T>//在list的末端插入值
void miniList<T>::push_back(const T& item){
	dnode<T> *temp,*curr;
	temp=new dnode<T>(item);
	if(listSize==0){//表示当前list中只有一个header
		header->next=temp;
		temp->next=header;
		header->prev=temp;
		temp->prev=header;
	}else if(listSize>0){
		//元素数不为0,在末端插入值其实就是在header前面插入值,因为list是串起来的环,先找到header的前驱
		curr=header->prev;
		//打开header的前驱和header,在中间插入新生成的temp
		curr->next=temp;
		temp->next=header;		
		header->prev=temp;
		temp->prev=curr;
	}
	listSize++;
}
template <typename T>
T& miniList<T>::back(){
	if(listSize>0)//元素个数不为0,返回末端元素的值,其实就是header前驱节点的值
		return header->prev->nodeValue;
}
template <typename T>//在顶端和在末端插入元素的方法类似,区别只是在顶端插入值时,插入的位置为header和header后继节点的中间。
void miniList<T>::push_front(const T& item){
	dnode<T> *curr,*temp;
	temp=new dnode<T>(item);
	if(listSize==0){
		header->next=temp;
		temp->prev=header;
		temp->next=header;
		header->prev=temp;
	}else if(listSize>0){
		curr=header->next;
		header->next=temp;
		temp->next=curr;
		temp->prev=header;
		curr->prev=temp;
	}
	listSize++;
}
template <typename T>
T& miniList<T>::front(){
	if(listSize>0)//元素个数不为0,返回顶端元素,其实就是header后继节点的节点值
		return header->next->nodeValue;
}
template <typename T>
int miniList<T>::size(){
	return listSize;//返回当前元素的个数
}
template <typename T>//返回一个游标,指向顶端元素,
typename miniList<T>::iterator miniList<T>::begin(){
	return iterator(header->next);//调用iterator的构造函数,将dnode类型的指针转换为游标
}
template <typename T>
typename miniList<T>::iterator miniList<T>::end(){
	return iterator(header);//与begin函数类似,区别是end返回的游标指向list的header,而不是一个具体的元素
}
template <typename T>//在固定的位置插入一个值
dnode<T>* miniList<T>::insert(const T& item,dnode<T> *curr){
	dnode<T> *tempNode,*tempPrev;
	tempNode=new dnode<T>(item);//新生成一个节点
	tempPrev=curr->prev;//找到插入位置的前驱节点

	tempPrev->next=tempNode;//插入这个新节点
	tempNode->next=curr;
	curr->prev=tempNode;
	tempNode->prev=tempPrev;
	listSize++;
	return tempNode;
}
template <typename T>//查找一个元素,返回它的地址,不在list当中则返回NULL
dnode<T>* miniList<T>::find(const T& item){
	dnode<T> *temp=header->next;
	//查找元素,直到找到该元素或者遍历完整个list
	while(temp->nodeValue!=item&&temp!=header){
		temp=temp->next;
	}
	if(temp!=header)//找到的该元素,返回它的地址
		return temp;
	return NULL;//遍历完整个list,说明不在list当中,返回NULL
}
template <typename T>//游标的两个构造函数,第一个生成一个空游标,第二个将dnode类型的指针转换为游标
miniList<T>::iterator::iterator(){
	node=NULL;
}
template <typename T>
miniList<T>::iterator::iterator(dnode<T> *p){
	node=p;
}
template <typename T>//重载的运算符,比较两个游标所指元素的元素值
bool miniList<T>::iterator::operator==(const iterator& rhs)const{
	return node->nodeValue==rhs.node->nodeValue;
}
template <typename T>
bool miniList<T>::iterator::operator!=(const iterator& rhs)const{
	return node->nodeValue!=rhs.node->nodeValue;
}
template <typename T>//重载的"*"运算符,返回游标所指元素的值
T& miniList<T>::iterator::operator*(){
	return node->nodeValue;
}


测试一下能不能正常的工作:

void main(){
	unsigned int i;	
	int a[]={1,6,2,5,6,7};
	miniList<int> list1(a,a+6);
	miniList<int>::iterator it;
	dnode<int> *temp;
	temp=list1.find(2);
	list1.insert(3,temp);
	list1.push_back(9);
	it=list1.begin();
	while(it!=list1.end()){
		cout<<*it<<" ";
		it++;
	}	
	while(1);
}
先用数组初始化一个list,生成一个空游标,并用list的end函数初始化,找到2的地址,在2前面插入3,在末端插入9,最后输出list的全部元素,测试结果:

按照预定的方式运行了,由于想让代码看起来简洁,没有进行异常的捕捉,也假设测试输入都是正确的。






2019-02-19 17:19:43 tx542009 阅读数 251
  • Python入门视频教程

    购买课程后,请扫码进入学习群,获取唐宇迪老师答疑 Python入门基础教程:python教程旨在掌握python开发的入门基础用法与其核心操作,便于大家在短时间内可以使用python进行后续的工作与学习。课程内容包括Python环境搭建(Anaconda方式)、变量、List基础结构、List索引、循环结构、判断结构、字典结构、文件处理、函数基础等。

    18161 人正在学习 去看看 唐宇迪

要说清楚列表数据类型,最好先讲一点儿理论背景,在信息技术界List这个词常常被使用不当。例如”Python Lists”就名不副实(名为Linked Lists),但他们实际上是数组(同样的数据类型在Ruby中叫数组)

一般意义上讲,列表就是有序元素的序列:10,20,1,2,3就是一个列表。但用数组实现的List和用Linked
List实现的List,在属性方面大不相同。 Redis lists基于Linked Lists实现。这意味着即使在一个list中有数百万个元素,在头部或尾部添加一个元素的操作,其时间复杂度也是常数级别的。用LPUSH命令在十个元素的list头部添加新元素,和在千万元素list头部添加新元素的速度相同。

那么,坏消息是什么?在数组实现的list中利用索引访问元素的速度极快,而同样的操作在linked list实现的list上没有那么快。

Redis Lists用linkedlist实现的原因是:对于数据库系统来说,至关重要的特性是:能非常快的在很大的列表上添加元素。另一个重要因素是,正如你将要看到的:Redis lists能在常数时间取得常数长度。

上面的一段话来自:redis 中文网 对于list的介绍,从中我们知道了list 的实现方式是 Linked Lists。

List 数据结构

Redis列表是简单的字符串列表,按照插入顺序排序。 你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

LPUSH 命令插入一个新元素到列表头部,而RPUSH命令 插入一个新元素到列表的尾部。当 对一个空key执行其中某个命令时,将会创建一个新表。 类似的,如果一个操作要清空列表,那么key会从对应的key空间删除。这是个非常便利的语义, 因为如果使用一个不存在的key作为参数,所有的列表命令都会像在对一个空表操作一样。

一些列表操作及其结果:

127.0.0.1:6379> rpush mylist A B C
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "C"
127.0.0.1:6379> lpush mylist first
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
4) "C"

注意:LRANGE 带有两个索引,一定范围的第一个和最后一个元素。这两个索引都可以为负来告知Redis从尾部开始计数,因此-1表示最后一个元素,-2表示list中的倒数第二个元素,以此类推。也可以理解:从 左边数是 0 开头,从右边数是-1开头。

List 常用命令

命令 描述
RPUSH key value [value …] 向存于 key 的列表的尾部插入所有指定的值
LPUSH key value [value …] 向存于 key 的列表的头部插入所有指定的值
127.0.0.1:6379> rpush mylist A B C
(integer) 3
127.0.0.1:6379> lpush mylist first
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
4) "C"
命令 描述
LINSERT key BEFORE & AFTER pivot value 把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面。
127.0.0.1:6379> linsert mylist before A "A before"
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "first"
2) "A before"
3) "A"
4) "B"
5) "C"
127.0.0.1:6379> linsert mylist after A "A after"
(integer) 6
127.0.0.1:6379> lrange mylist 0 -1
1) "first"
2) "A before"
3) "A"
4) "A after"
5) "B"
6) "C"
命令 描述
LPOP key 移除并且返回 key 对应的 list 的第一个元素。
RPOP key 移除并返回存于 key 的 list 的最后一个元素。
LREM key count value 从存于 key 的列表里移除前 count 次出现的值为 value 的元素。

注:这个 count 参数通过下面几种方式影响这个操作:
count > 0: 从头往尾移除值为 value 的元素。
count < 0: 从尾往头移除值为 value 的元素。
count = 0: 移除所有值为 value 的元素。
比如, LREM list -2 “hello” 会从存于 list 的列表里移除最后两个出现的 “hello”。

127.0.0.1:6379> lpop mylist
"first"
127.0.0.1:6379> rpop mylist
"C"
127.0.0.1:6379> lrange mylist 0 -1
1) "A before"
2) "A"
3) "A after"
4) "B"
127.0.0.1:6379> rpush mylist A B B C D E A C C
(integer) 9
127.0.0.1:6379> lrem mylist 1 B
(integer) 1
127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "C"
4) "D"
5) "E"
6) "A"
7) "C"
8) "C"
127.0.0.1:6379> lrem mylist -1 A
(integer) 1
127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "C"
4) "D"
5) "E"
6) "C"
7) "C"
127.0.0.1:6379> lrem mylist 0 C
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "D"
4) "E"

从上面的演示中可以看出,当count 不等于 0 的是后,只会匹配一个元素进行删除。当 count 等于 0 的时候,会把所有相同的元素进行删除。

命令 描述
LTRIM key start stop 修剪(trim)一个已存在的 list,这样 list 就会只包含指定范围的指定元素。

注:start 和 stop 都是由0开始计数的, 这里的 0 是列表里的第一个元素(表头),1 是第二个元素,以此类推。

例如: LTRIM foobar 0 2 将会对存储在 foobar 的列表进行修剪,只保留列表里的前3个元素。

127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "D"
4) "E"
127.0.0.1:6379> ltrim mylist 0 2
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "D"

mylist 中的 E 元素被删掉了。

命令 描述
LRANGE key start stop 返回存储在 key 的列表里指定范围内的元素。

注:start 和 end 偏移量都是基于0的下标,即list的第一个元素下标是0(list的表头),第二个元素下标是1,以此类推。

偏移量也可以是负数,表示偏移量是从list尾部开始计数。 例如, -1 表示列表的最后一个元素,-2 是倒数第二个,以此类推。

注:这里偏移量是包头包尾的。不像java是包头不包尾,这点需要注意。

127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "D"

start 为 0,end 为 -1 ,则为显示mylist 中从头到尾的数据。

命令 描述
LINDEX key index 返回列表里的元素的索引 index 存储在 key 里面

注:下标是从 0 开始的

127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "D"
127.0.0.1:6379> lindex mylist 1
"B"
命令 描述
LLEN key 返回存储在 key 里的list的长度
127.0.0.1:6379> llen mylist
(integer) 3
命令 描述
LSET key index value 设置 index 位置的list元素的值为 value
127.0.0.1:6379> lset mylist 2 "B set update "
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "A"
2) "B"
3) "B set update "
命令 描述
BLPOP key [key …] timeout BLPOP 是阻塞式列表的弹出原语
BRPOP key [key …] timeout BRPOP 是阻塞式列表的弹出原语
127.0.0.1:6379> rpush mylist a b c
(integer) 3
127.0.0.1:6379> brpop mylist list 0
1) "mylist"
2) "c"
127.0.0.1:6379> brpop mylist list 20
1) "mylist"
2) "b"

List 还有很多其他的命令,大家可以看下这个链接:
List 命令大全

之前准备学习的时候写博客,可是都没有坚持下去,希望这次可以有始有终。
Redis 坚持第一天 :为什么要使用 redis ?
Redis 坚持第二天 :Redis 的安装与启动
Redis 坚持第三天 :Redis 使用配置文件启动,常见配置学习。
Redis 坚持第四天 :

  1. Redis 五种常见的数据结构:String
  2. Redis 五种常见的数据结构:Hash
  3. Redis 五种常见的数据结构:List
2019-07-18 20:03:58 weixin_44043580 阅读数 44
  • Python入门视频教程

    购买课程后,请扫码进入学习群,获取唐宇迪老师答疑 Python入门基础教程:python教程旨在掌握python开发的入门基础用法与其核心操作,便于大家在短时间内可以使用python进行后续的工作与学习。课程内容包括Python环境搭建(Anaconda方式)、变量、List基础结构、List索引、循环结构、判断结构、字典结构、文件处理、函数基础等。

    18161 人正在学习 去看看 唐宇迪

List

特性:有序性,可重复性
1.添加元素 :使用add方法
List list = new ArrayList();
list.add(1);
list.add(5);
list.add(5);
list.add(16);
list.add(3);
list.add(-1);
list.add(9);

2.删除元素 :使用remove方法
list.remove(1);//remove中填写索引

3.遍历元素有三种方法

  • 使用for循环
    for (int i = 0; i < list.size() ; i++) {
    System.out.println(list.get(i));
    }

  • 使用for-each循环

for (Integer list1:list){

     System.out.println(list1);

    }

  • 使用iterator
    Iterator iterator = list.iterator();
    while (iterator.hasNext()){             //判断iterator后面是否有值
    System.out.println(iterator.next());
    }
2018-12-24 22:39:22 qq_32447301 阅读数 1086
  • Python入门视频教程

    购买课程后,请扫码进入学习群,获取唐宇迪老师答疑 Python入门基础教程:python教程旨在掌握python开发的入门基础用法与其核心操作,便于大家在短时间内可以使用python进行后续的工作与学习。课程内容包括Python环境搭建(Anaconda方式)、变量、List基础结构、List索引、循环结构、判断结构、字典结构、文件处理、函数基础等。

    18161 人正在学习 去看看 唐宇迪

第一种方式使用工具类进行比较

package com.hzbank.counter.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * lists数据比对
 * @author nick
 */
public class ListUtils {

   /* public static void main(String[] args) {
        List<String> list1 = new ArrayList<String>();
        List<String> list2 = new ArrayList<String>();
        for (int i = 0; i < 30000; i++) {
            list1.add("test" + i);
        }
        for (int i = 0; i < 80000; i++) {
            list2.add("test" + i * 2);
        }
        getDiffrentOne(list1, list2);
        getDiffrentTwo(list1, list2);
        getDiffrentThree(list1, list2);
        getDiffrentFour(list1, list2);

    }*/

    // 方法1,两层遍历查找,遍历次数为list1.size()*list2.size(),有点蠢
    private static List<String> getDiffrentOne(List<String> list1, List<String> list2) {
        // diff 存放不同的元素
        List<String> diff = new ArrayList<String>();
        // 开始查找的时间,用于计时
        /*long start = System.currentTimeMillis();*/
        for (String str : list1) {
            if (!list2.contains(str)) {
                diff.add(str);
            }
        }
        // 计时
        /*System.out.println("方法1 耗时:" + (System.currentTimeMillis() - start) + " 毫秒");*/
        return diff;
    }

    // 方法2,两层遍历查找,用retainAll()方法查找,也很蠢,方法底层依旧是两层遍历
    private static List<String> getDiffrentTwo(List<String> list1, List<String> list2) {
        /*long start = System.currentTimeMillis();*/
        list1.retainAll(list2);// 返回值是boolean
        /*System.out.println("方法2 耗时:" + (System.currentTimeMillis() - start) + " 毫秒");*/
        return list1;
    }

    // 方法3,用Map存放List1和List2的元素作为key,value为其在List1和List2中出现的次数
    // 出现次数为1的即为不同元素,查找次数为list1.size() + list2.size(),较方法1和2,是极大简化
    private static List<String> getDiffrentThree(List<String> list1, List<String> list2) {
        List<String> diff = new ArrayList<String>();
        /*long start = System.currentTimeMillis();*/
        Map<String, Integer> map = new HashMap<String, Integer>(list1.size() + list2.size());
        // 将List1元素放入Map,计数1
        for (String string : list1) {
            map.put(string, 1);
        }
        // 遍历List2,在Map中查找List2的元素,找到则计数+1;未找到则放入map,计数1
        for (String string : list2) {
            Integer count = map.get(string);
            if (count != null) {
                map.put(string, ++count);// 此处可优化,减少put次数,即为方法4
                continue;
            }
            map.put(string, 1);
        }
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            if (entry.getValue() == 1) {
                diff.add(entry.getKey());
            }
        }
        /*System.out.println("方法3 耗时:" + (System.currentTimeMillis() - start) + " 毫秒");*/
        return diff;
    }

    // 优化方法3,减少put次数
    private static List<String> getDiffrentFour(List<String> list1, List<String> list2) {
        List<String> diff = new ArrayList<String>();
       /* long start = System.currentTimeMillis();*/
        Map<String, Integer> map = new HashMap<String, Integer>(list1.size() + list2.size());
        List<String> maxList = list1;
        List<String> minList = list2;
        if (list2.size() > list1.size()) {
            maxList = list2;
            minList = list1;
        }
        for (String string : maxList) {
            map.put(string, 1);
        }
        for (String string : minList) {
            Integer count = map.get(string);
            if (count != null) {
                map.put(string, ++count);
                continue;
            }
            map.put(string, 1);
        }
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            if (entry.getValue() == 1) {
                diff.add(entry.getKey());
            }
        }
        /*System.out.println("方法3 耗时:" + (System.currentTimeMillis() - start) + " 毫秒");*/
        return diff;

    }
}

第二种使用com.google.common.collect的工具类

<!--Google guava工具类-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>
            List<String> listA = new ArrayList<String>();
            List<String> listB = new ArrayList<String>();
            for (SessionIdB sessionIdB : sessionIdBll) {
                listA.add(sessionIdB .getSessionIdB());
            }
            for (SessionIdA sessionIdA : sessionIdAll) {
                listB.add(sessionIdA .getSessionIdA());
            }
            HashSet<String> setA = new HashSet<String>(listA);
            HashSet<String> setB = new HashSet<String>(listB);
            Sets.SetView<String> difference = Sets.difference(setA, setB);
            List<String> listC=new ArrayList<String>();
            for (String string : difference) {
                logger.info("-----获取的sessionId--------"+string);
                listC.add(string);
            }

《参考代码如下》
set的交集, 并集, 差集

HashSet setA = newHashSet(1, 2, 3, 4, 5);  
HashSet setB = newHashSet(4, 5, 6, 7, 8);  
   
SetView union = Sets.union(setA, setB);  
System.out.println("union:");  
for (Integer integer : union)  
    System.out.println(integer);           //union:12345867
   
SetView difference = Sets.difference(setA, setB);  
System.out.println("difference:");  
for (Integer integer : difference)  
    System.out.println(integer);        //difference:123
   
SetView intersection = Sets.intersection(setA, setB);  
System.out.println("intersection:");  
for (Integer integer : intersection)  
    System.out.println(integer);  //intersection:45

第三种检查参数是否有值或者为空


方法一(数据量大,效率低):
if(list!=null && list.size()>0){
}

方法二(数据量大,效率高):
if(list!=null && !list.isEmpty()){
}

//use java
if(list!=null && list.size()>0)
'''
if(str!=null && str.length()>0)
'''
if(str !=null && !str.isEmpty())

//use guava
if(!Strings.isNullOrEmpty(str))

//use java
if (count <= 0) {                                                                                           
    throw new IllegalArgumentException("must be positive: " + count);         
}    

//use guava
Preconditions.checkArgument(count > 0, "must be positive: %s", count);  
2016-08-10 14:23:50 baiyulinlin1 阅读数 30075
  • Python入门视频教程

    购买课程后,请扫码进入学习群,获取唐宇迪老师答疑 Python入门基础教程:python教程旨在掌握python开发的入门基础用法与其核心操作,便于大家在短时间内可以使用python进行后续的工作与学习。课程内容包括Python环境搭建(Anaconda方式)、变量、List基础结构、List索引、循环结构、判断结构、字典结构、文件处理、函数基础等。

    18161 人正在学习 去看看 唐宇迪

 

博客已转移

 

一、简介

         存储List数据到本地的方式有很多种,对于不想用sqlite或者其他方式,又或是数据量很少的话,不妨可以试下用 SharedPreferences保存。由于SharedPreferences只能保存Map型的数据,必须要做其他转换才行。

 

二、应用场景

         用于保存各种List数据,最常见的莫过于,ListView、Gridviw中的数据,支持类型有:

(1)List<String>

(2)List<Map<String,Object>>

(3)List<JavaBean>

三、项目实战

(1)、ListDataSave工具类,这里处理的方式时用gson把List转换成json类型,再利用SharedPreferences保存的。

gson的下载地址:http://download.csdn.net/detail/baiyulinlin1/9599507

 

public class ListDataSave {
	private SharedPreferences preferences;
	private SharedPreferences.Editor editor;

	public ListDataSave(Context mContext, String preferenceName) {
		preferences = mContext.getSharedPreferences(preferenceName, Context.MODE_PRIVATE);
		editor = preferences.edit();
	}

	/**
	 * 保存List
	 * @param tag
	 * @param datalist
	 */
	public <T> void setDataList(String tag, List<T> datalist) {
		if (null == datalist || datalist.size() <= 0)
			return;

		Gson gson = new Gson();
		//转换成json数据,再保存
		String strJson = gson.toJson(datalist);
		editor.clear();
		editor.putString(tag, strJson);
		editor.commit();

	}

	/**
	 * 获取List
	 * @param tag
	 * @return
	 */
	public <T> List<T> getDataList(String tag) {
		List<T> datalist=new ArrayList<T>();
		String strJson = preferences.getString(tag, null);
		if (null == strJson) {
			return datalist;
		}
		Gson gson = new Gson();
		datalist = gson.fromJson(strJson, new TypeToken<List<T>>() {
		}.getType());
		return datalist;

	}
}

(2)、Userbean类,简单处理下,名字和年龄

 

 

public class Userbean {
	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}


(3)、MainActivity类

 

 

public class MainActivity extends Activity implements OnClickListener {
	Context mContext;
	ListDataSave dataSave;
	private ArrayList<Userbean> listBean;
	private ArrayList<String> listString;
	private ArrayList<Map<String, Object>> listMap;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		initView();

	}

	private void initView() {
		findViewById(R.id.btn_addString).setOnClickListener(this);
		findViewById(R.id.btn_addJavaBean).setOnClickListener(this);
		findViewById(R.id.btn_addMap).setOnClickListener(this);
		findViewById(R.id.btn_getString).setOnClickListener(this);
		findViewById(R.id.btn_getJavaBean).setOnClickListener(this);
		findViewById(R.id.btn_getMap).setOnClickListener(this);
		mContext = getApplicationContext();
		dataSave = new ListDataSave(mContext, "baiyu");
		listString = new ArrayList<String>();
		listBean = new ArrayList<Userbean>();
		listMap = new ArrayList<Map<String, Object>>();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_addString:
			String s = "小名";
			listString.add(s);
			dataSave.setDataList("string", listString);

			break;
		case R.id.btn_getString:
			Toast.makeText(mContext, dataSave.getDataList("string").toString(), Toast.LENGTH_SHORT).show();
			break;
		case R.id.btn_addJavaBean:
			Userbean user = new Userbean();
			user.setName("小白");
			user.setAge(16);
			listBean.add(user);
			dataSave.setDataList("javaBean", listBean);
			break;
		case R.id.btn_getJavaBean:

			Toast.makeText(mContext, dataSave.getDataList("javaBean").toString(), Toast.LENGTH_SHORT).show();

			break;
		case R.id.btn_addMap:
			Map<String, Object> map=new HashMap<String, Object>();
			map.put("name","大白");
			map.put("age", 18);
			listMap.add(map);
			dataSave.setDataList("listMap", listMap);
			break;
		case R.id.btn_getMap:
			Toast.makeText(mContext, dataSave.getDataList("listMap").toString(), Toast.LENGTH_SHORT).show();
			break;
		}

	}

}

(4)Demo链接:http://download.csdn.net/detail/baiyulinlin1/9599788
 

 

查找list中重复数据

阅读数 3791

redis数据结构之List

阅读数 127

没有更多推荐了,返回首页