zoukankan      html  css  js  c++  java
  • 队列、循环队列、反射的简单应用

    今天主要是 队列 循环队列的学习。以及反射的应用,基于反射我们学习了如何只做一个通用的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里面找一下吧

  • 相关阅读:
    C++Primer中文版(第4版)第五章习题答案
    C++Primer中文版(第4版)第四章习题答案
    利用矩阵奇异值分解对图像进行压缩
    利用奇异值分解压缩图像
    程序莫名其妙地老死
    图像边沿平滑处理的matlab实现
    Zend Server搭建网站备注
    利用矩阵的n次方求图的连通性
    matlab增加数组元素的效率分析
    PHP语法总结
  • 原文地址:https://www.cnblogs.com/letben/p/5185035.html
Copyright © 2011-2022 走看看