您的位置:首页 > 其它

队列、循环队列、反射的简单应用

2016-02-08 15:57 344 查看
今天主要是 队列 循环队列的学习。以及反射的应用,基于反射我们学习了如何只做一个通用的dao层。利用这个基本逻辑处理类我们可以实现对于数据库的插入和查看。当然剩下的方法还没有写,一会儿尝试写出来。不过最好先把刚刚那段代码抄一遍,然后背一下。做到融会贯通。然后其实可以再背一遍JDBCTemplate模板。

队列与循环队列:

这个 版本的反射的应用应该是 1.0版本的。比起前面那一张的那个 坑爹类,可强太多了。只有3个方法,但是 要展示的 反射的应用 却用的比较到位。

以下例程

队列:

package MyQueue;
public class MyQueue {//线性队列
private Object[] obs = new Object[5];
private int start=-1;//队头
private int end=-1;//队尾
/**
* 添加元素,这个可以封装Object[] 当然也可把我们昨天写的链表结构拿过来,用作对象的存储
* @param object
*/
public void add(Object object){
if(end>=obs.length){
System.out.println("队列已满");
return ;
}
obs[++end]=object;
}
/**
* 得到队列的开始元素
* @return
*/
public Object getStart(){
return obs[start+1];
}
/**
* 得到队尾元素
* @return
*/
public Object getEnd(){
return obs[end];
}
/**
* 得到队列的长度
* @return
*/
public int getSize(){
return end-start;
}
/**
* 出队操作
* @return
*/
public Object putOut(){
start++;
Object object = obs[start];
obs[start]=null;
return object;
}
/**
* 按照队列顺序查看队列中的元素
*/
public void lookout(){
for(int i=start+1;i<end+1;i++){
System.out.println(obs[i]);
}
}
}


循环队列:

package MyQueue;
/**
* 线性队列的存在总是很爽,但是很浪费空间,如果每次都能让队列满载,这样就很节省空间。
* @author Administrator
*浪费一个空间作为队满的标志
*修改的时候,总是要记得%,不能直接++
*对比的时候也要记得,%
*/
public class MyCircleQueue {
Object[] obs = new Object[5];
private int start=0;//队头
private int end=0;//队尾
/**
* 为循环队列添加元素
* @param object
*/
public void add(Object object){
if(isFull()){
System.out.println("队列已满,请等待");
return ;
}
end=(end+1)%obs.length;
obs[end]=object;
}
/**
* 判断队列是否已满,消耗一个空间用作队满的标志
* @return
*/
public boolean isFull(){
return (end+1)%obs.length==start;
}
/**
* 判断队列是否为空,如果start==(end)%obs.length 则队空
* @return
*/
public boolean isEmpty(){
return (end)%obs.length==start;
}
/**
* 出队操作,里面的队头不可能大于5,所以 上面关于 队满和队空的判断是合理的。并不用为strat也进行求余操作。
* @return
*/
public Object putout(){
if(isEmpty()){
System.out.println("队列中没有元素");
return null;
}
Object object = obs[start];
obs[start]=null;
start=(start+1)%obs.length;
return object;
}
/**
* 得到循环队列中等待元素的数量
* @return
*/
public int getSize(){//如果数组短还好,可以直接访问得到数据个数,如果数组长了这样就不划算了,应该可以有算法
//数组长度一定小于obs.length()
int i=0;
for(;i<obs.length;i++){
if((end+i)%obs.length==start){
break;
}
}
return obs.length-i;
}

/**
* 按照队列顺序额查看队列中的元素
*/
public void lookout(){
if(isEmpty()){
System.out.println("队列为空");
return ;
}
int i=0;
while((start+i)%obs.length!=(end+1)%obs.length){
System.out.println(obs[(start+i)%obs.length]);
i++;
}
}
}


基于jdbc的template:

package com.letben.dao;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.letben.bean.user_tb;
import com.letben.util.JDBCTemplate;
/**
* 当前BaseDao使用的前提是:类名和表名要保持一致,属性名和字段名要保持一致
* 之后我们会写一个映射表,来解决数据库和表名命名需要符合规范的问题
* @author Administrator
* 抽空补齐 改 和删!
*/
public class BaseDao extends JDBCTemplate{
/*
static String className=null;
static String tableName = null;
* 并且发现老师的代码里面每一个地方都有className。所以不妨在程序开始的时候,写一个出来。
* 表名也是
BaseDao(){}
BaseDao(Class c){
className = c.getName();
tableName = className.substring(className.lastIndexOf(".")+1);
}
static {
//静态块儿并实现不了,需要一个构造函数
}
* 类型安全问题,是不是可以把List后面加一个泛型。
* @param c
* @return
*
不不不,这些东西不能放在BaseDao,里面而要放在对应的 user_tb 的dao里面
*/
public     void addObject(Object obj){
Class c  = obj.getClass();
String className = c.getName();
String tableName = className.substring(className.lastIndexOf(".")+1);

StringBuffer sql = new StringBuffer();
//        对于我们要反复修改的字符串语句来讲,我们最好使用StringBuffer 以节省空间。每new的一个String都会在内存中占用一个地址
//组拼sql语句: insert into tableName (column1,column2...) values (value1,value2...);
sql.append(" insert into ");
sql.append(tableName);
List<String> fields = new ArrayList<String>();
List values = new ArrayList();
Method[] methods = c.getMethods();
for (Method method : methods) {
//组拼时,需要对应的属性和值,那么新建了两个集合,通过整体添加的方式保持两者对应一致。
String methodName = method.getName();
if(methodName.startsWith("get")&&!methodName.equalsIgnoreCase("getclass")){
String fieldName = methodName.substring(3);
fields.add(fieldName);
try {
values.add(method.invoke(obj, new Object[]{}));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

sql.append(" ( ");//这个里面空格可以多不能少,所以尽量在每一个单词前后都加上空格,以免字符连在一起,sql无法解析
for(int i=0;i<fields.size();i++){
if(i==fields.size()-1){
sql.append(fields.get(i));
}else{
sql.append(fields.get(i)+",");
}
}
sql.append(" ) ");
sql.append(" values ");
sql.append(" ( ");
for (int i = 0; i < values.size(); i++) {
if(i==values.size()-1){
sql.append("'"+values.get(i)+"'");
}else{
sql.append("'"+values.get(i)+"',");
}
}
sql.append(" ) ");
System.out.println(sql.toString());
updateData(sql.toString());
}

public Object getObjectById(Class c,int id){
String className = c.getName();//大类名
String tableName = className.substring(className.lastIndexOf(".")+1);//表名,因为我们的前提是类名与表名一致
String sql = "select * from "+tableName+" where id = "+id;
ResultSet resultSet = query(sql);
Object object  = null;
try {
object = c.newInstance();
if(resultSet.next()){
Method[] methods = c.getMethods();
for (Method method : methods) {
String methodName = method.getName();
if(methodName.startsWith("set")){
String fieldName = methodName.substring(3);
Class[] cla=method.getParameterTypes();
if(cla[0]==String.class){//要求属性和字段都放是String和name的依然没有那么通用
method.invoke(object, new Object[]{resultSet.getString(fieldName)});
}else{
method.invoke(object, new Object[]{resultSet.getInt(fieldName)});
}
//method.invoke(object,new Object[]{resultSet.getString(fieldName)});
//取不出来,事实证明真的不通用,只能是对应的读取
}
}
}
} catch (SQLException e) {//resultSet.next();
e.printStackTrace();
} catch (InstantiationException e) {//c.newInstance
e.printStackTrace();
} catch (IllegalAccessException e) {//c.newInstance
e.printStackTrace();
} catch (IllegalArgumentException e) {//invoke
e.printStackTrace();
} catch (InvocationTargetException e) {//invoke
e.printStackTrace();
}
return object;
}

public List getAllObject(Class c){
String className = c.getName();//得到类名
System.out.println(className);
String tableName = className.substring(className.lastIndexOf(".")+1);//得到表名或者 类的类名。
System.out.println(tableName);
String sql  = "select * from "+ tableName;
ResultSet resultSet = query(sql);//这是JDBCTemplate里面的方法
//        System.out.println("****************");
List list = new ArrayList();
Object object = null;
try{
while(resultSet.next()){
object=c.newInstance();
Method[] methods = c.getMethods();//得到所有公开的方法。
for (int i=0;i<methods.length;i++){
Method m=methods[i];//得到当前遍历到的这个方法
//                    System.out.println(m);
String methodName = m.getName();
//                    System.out.println(methodName);
if(methodName.startsWith("set")){//如果这个方法以set开头
String fieldName = methodName.substring(3);//得到对应属性名称
Class[] cla = m.getParameterTypes();//得到m方法的全部参数的参数类型。
if(cla[0]==String.class){
//                            m.invoke(object, new Object(){});
//方法召唤,反射得到的方法再进行调用,先传一个类作为实际使用这个方法的参数进去,后面是参数列表
m.invoke(object,resultSet.getString(fieldName));
//等效于:object.set<fieldName>(resultSet.getString(fieldName));
//即:对象把从结果集里面取出来的属性值赋给对应的属性。
}else{
m.invoke(object, resultSet.getInt(fieldName));
//我们常见的getters和setters的语句是:对象.setField(FieldValue);
//在反射里面这样写: 方法(对象,参数们)所以针对参数们:的标准写法是:new Object(){p1,p2...}
}
}
}
//这些轮完一圈儿,说明一个对象已经赋值完成。可以使用。故:
list.add(object);
object=null;
}
}catch(Exception e){
e.printStackTrace();
}
return list;
}
public static void main(String[] args) {
BaseDao baseDao= new BaseDao();
List<com.letben.bean.user_tb> list =baseDao.getAllObject(user_tb.class);//刚刚到这里有点儿蒙,忘记了类名.class
for (user_tb user_tb : list) {
System.out.println(user_tb);
}
}
}


那个 jdbc:刚写过了【笑哭】去那篇名叫jdbc的blog里面找一下吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: