zoukankan      html  css  js  c++  java
  • java基础测试

    测试一:

    第1题:Collection和Collections有什么关系?List和Set有什么异同点?Map有哪些常用类,各有什么特点?
    答:Collection是集合操作的接口,Set和List都继承自它;Collections是一个集合工具类,其中方法sort()可以对实现了Comparable
    接口的类进行排序。addAll()方法为集合添加内容,binarySearch()方法用于集合检索,reverse()将集合内容翻转等。两者关系:
    Collections提供了操作Collection集合内容的方法。
    List和Set相同点:都继承自Collection,都是存放单值的集合,都只能存放对象类型的数据,都可以迭代输出;不同点:List集合中允许有
    重复的元素,数据是有序排列的;Set集合中不允许有重复的元素,有有序的子类TreeSet,无序的子类HashSet。
    Map常用类有HashMap、TreeMap、HashTable。HaspMap是异步的,性能较高,线程不安全;HashTable是同步的,性能较低,线程安全。
    TreeMap是可以按照key值排序的。

    第2题:为什么需要配置path,什么时候需要classpath?
    答:path指定运行路径,搜索可执行文件,如果没配置,在windows cmd中输入java和javac,就会提示找不到命令。
    classpath指定一个路径,用于搜索java编译或者运行时需要用到的类,否则提示找不到类。

    第3题:从键盘接受一个数字,列出该数字的中文表示格式,例如:键盘输入123,打印出一二三;键盘输入3103,打印出三一零三。

    public class Test3 {
        private static String[] chineses;
        public static void main(String[] args) {
            // 初始化String 数组存放中文数字
            chineses = new String[] { "零", "一", "二", "三", "四", "五", "六", "七", "八",
                    "九", "十" };
            boolean flag = true;
            System.out.println("请输入数字:");
            // 从键盘输入
            Scanner scan = new Scanner(System.in);
            String line = scan.nextLine();
            // 循环检测用户输入
            while (flag) {
                if (!line.matches("^\d+?")) {
                    System.out.println("输入数据格式不正确,请重新输入");
                    // 读取下一行
                    line = scan.nextLine();
                } else {
                    // 停止循环
                    flag = false;
                }
            }
            // 调用静态方法
            print(line);
        }
        /**
         * 根据传入的阿拉伯数字转化为中文数字
         * @param str
         */
        public static void print(String str) {
            //讲字符串转化为字符数组
            char[] chars = str.toCharArray();
            //定义一个可变字符串
            StringBuffer sb = new StringBuffer();
            //遍历字符数组
            for (char c : chars) {
                //将数字字符转化为整型数字
                Integer num = Integer.parseInt(c+"");
                //添加到字符串中
                sb.append(chineses[num]);
            }
            System.out.println(sb.toString());
        }
    }

    第4题:求斐波那契数列第n项,n<30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

    public class Test4 {
        
        public static void main(String[] args) {
            System.out.println("请输入正整数n,n<30");
            // 从键盘输入
            Scanner scan = new Scanner(System.in);
            boolean flag = true;
            String numStr = null;
            int num = 0;
            // 循环检测用户输入
            while (flag) {
                // 判断用户输入是否为整型
                if (scan.hasNextInt()) {
                    //用户输入了整型
                    num = scan.nextInt();
                    if (num >= 30) {
                        System.out.println("请输入小于30的数字");
                        //用户仍有可能输入一个非数字
                        numStr = scan.nextLine();
                    } else {
                        //终止循环
                        flag = false;
                    }
                } else {
                    //用户没有输入整型
                    System.out.println("输入数据格式不正确,请重新输入!");
                    numStr = scan.nextLine();
                }
            }
            System.out.println("斐波那契数列第" + num + "项为:" + fibonacci(num));
        }
        /**
         * 递归调用fibonacci()
         * @param 
         * @return 
         */
        public static int fibonacci(int n) {
            if (n == 1 || n == 0) {
                return n;
            } else {
                //当n>=2是每一项都等于前面两项的和
                return fibonacci(n - 1) + fibonacci(n - 2);
            }
        }
    }

    第5题:编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如:
    原始字符串是"abc",打印得到下列所有组合情况:
    "a" "b" "c"
    "ab" "bc" "ca" "ba" "cb" "ac"
    "abc" "acb" "bac" "bca" "cab" "cba"

    public class Test5 {
        static char[] chars="abc".toCharArray();
        public static void main(String[] args) {
            for(int i=0;i<chars.length;i++){
                //取得每一个字符
                List<Integer> list=new ArrayList<Integer>();
                list.add(i);
                recur(list);
            }
        }
        //使用递归,每次加上列表中不存在的一个字符
        private static void recur(List<Integer> list){
            print(list);
            for(int i=0;i<chars.length;i++){
                if(!list.contains(i)){
                    //根据已有的集合构造新的集合
                    List<Integer> temp=new ArrayList<Integer>(list);
                    temp.add(i);
                    recur(temp);
                }
            }
        }
        //打印列表内容
        private static void print(List<Integer> list){
            for(Integer i:list)
                System.out.print(chars[i]+"");
            System.out.println();
        }
    }

    6、 分析运行结果,说明原理。

    class A {
        void fun1() {
            System.out.println(fun2());
        }
    
        int fun2() {
            return 123;
        }
    }
    
    public class Test6 extends A {
        int fun2() {
            return 456;
        }
    
        public static void main(String args[]) {
            Test6 b = new Test6();
            b.fun1();
            A a = b;
            System.out.println(a instanceof Test6);
            a.fun1();
        }
    }

    答:由于子类B没有覆写父类A的fun1()方法,因此b.fun1(),是调用由父类继承而来的fun1(),在fun1()中调用了fun2()时候由于fun2()
    已经被子类覆写,因此调用的是子类的fun2();所以打印第一条结果为456;
    A a = b;子类向上转型为父类实例化,a instanceof B 结果为true,此时当前对象为子类的对象,所以在fun1()中调用fun2()是为子类
    的fun2(),因此打印第二条结果为456。

    第7题: 编写一个可以获取文件扩展名的函数,形参接收一个文件名字符串,返回一个扩展名字符串。

    public class Test7 {
        public static void main(String[] args) {
            System.out.println("请输入一个包含拓展名的文件名字符串:");
            Scanner scan = new Scanner(System.in);
            String str = scan.nextLine();
            //从后往前查找.第一次出现的为之
            int dot = str.lastIndexOf(".");
            //从.出现的位置后面
            System.out.println("扩展名为:"+str.substring(dot+1));
        }
    }

    第8题: 编写一个延迟加载的单例设计模式。

    public class Test8 {
        private static Test8 instance ;
        //讲构造方法私有
        private Test8() {
            
        }
        //通过静态方法返回instance对象
        public static Test8 getInstance(){
            if(instance == null){
                //加入同步操作,线程安全
                synchronized (Test8.class) {
                    if(instance == null){
                        //实例化单例对象
                        instance = new Test8();
                    }
                }
            }
            return instance;
        }
    }

    第9题:编写程序,将指定目录下所有.java文件拷贝到另一个目录中,并将扩展名改为.txt

    public class Test9 {
        private static File directory;
    
        public static void main(String[] args) {
            File src = new File("C:\src");
            directory = new File("c:\directory");
            //目录不存在则创建
            if(!directory.exists()){
                directory.mkdir();    
            }
            list(src);
            System.out.println("文件已拷贝至c:\directory目录中");
        }
        /**
         * 递归调用函数
         * @param file
         */
        public static void list(File f) {
            if (f.isDirectory()) {
                //获得此目录下所有文件名(含绝对路径)
                File[] files = f.listFiles();
                //遍历子文件及目录
                if(files!=null){
                    for (File file : files) {
                        list(file);
                    }
                }
                
            } else {
                //是文件就直接拷贝,相同文件名拷贝至同一目录会被覆盖
                copyFile(f);
            }
        }
        
        public static void copyFile(File file) {
            String newName = null;
            try {
                //获得文件的原始名字
                String name = file.getName();
                //只处理java文件
                if (name.contains(".java")) {
                    //将.java后缀改成.txt后缀
                    newName = name.replace(".java", ".txt");
                    //文件输出流
                    FileOutputStream fos = new FileOutputStream(new File(directory,newName));
                    //文件输入流
                    FileInputStream fis = new FileInputStream(file);
                    int len = 0;
                    //定义数组存储读取到的数据
                    byte[] b = new byte[1024];
                    //循环读入源文件
                    while ((len = fis.read(b)) != -1) {
                        //边读边写
                        fos.write(b, 0, len);
                    }
                    //关闭输入输出流
                    fis.close();
                    fos.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    10、 小明的妈妈每天会给他20元零花钱。平日里,小明先花掉一半,再把一半存起来。 每到周日,小明拿到钱后会把所有零花钱花掉一半。 请编程计算,从周一开始,小明需要多少天才能存够100元?

    public class Test10 {
        public static void main(String[] args) {
            System.out.println("需要"+save()+"天");
        }
        public static int save() {
            int day = 0, money = 0;
            //money>=100停止循环
            while (money < 100) {
                //增加天数
                day++;
                //判断是否到达周末
                if (day % 7 == 0) {
                    money += 20;
                    money -= money / 2;
                } else {//平时得20花10相当于得10元
                    money += 10;
                }
                
            }
            return day;
        }
    }

    测试二:

    第1题:有五个学生,每个学生有3门课(语文、数学、英语)的成绩,写一个程序接收从键盘输入学生的信息,输入格式为:name,30,30,30(姓名,三门课成绩),然后把输入的学生信息按总分从高到低的顺序写入到一个名称"stu.txt"文件中。 要求:stu.txt文件的格式要比较直观,打开这个文件,就可以很清楚的看到学生的信息。

    //学生类实现Comparable接口
    class Student implements Comparable<Student>{
        private String name;
        private int chinese;
        private int math;
        private int english;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getChinese() {
            return chinese;
        }
        public void setChinese(int chinese) {
            this.chinese = chinese;
        }
        public int getMath() {
            return math;
        }
        public void setMath(int math) {
            this.math = math;
        }
        public int getEnglish() {
            return english;
        }
        public void setEnglish(int english) {
            this.english = english;
        }
        
        @Override
        public String toString() {
            return "Student [name=" + name + ", chinese=" + chinese + ", math="
                    + math + ", english=" + english + "]";
        }
        /**
         * 计算总分
         * @return
         */
        public int getSum(){
            return this.chinese+this.english+this.math;
        }
        /**
         * 按照总分比较
         */
        @Override
        public int compareTo(Student o) {
            return o.getSum()-this.getSum();
        }
    }
    public class Test1 {
        public static void main(String[] args) {
            System.out.println("请输入5个学生信息,输入格式为name,30,30,30");
            Scanner scan = new Scanner(System.in);
            List<Student> list = new ArrayList<Student>();
            //循环录入学生信息
            for(int i=0;i<5;i++){
                String line = scan.nextLine();
                //按照“,”将字符串拆分成字符串数组
                String[] split = line.split(",");
                //实例化学生类并赋值
                Student stu = new Student();
                stu.setName(split[0]);
                stu.setChinese(Integer.parseInt(split[1]));
                stu.setMath(Integer.parseInt(split[2]));
                stu.setEnglish(Integer.parseInt(split[3]));
                //将学生信息加入集合中
                list.add(stu);
            }
            //使用Collections工具类对集合中的对象排序
            Collections.sort(list);
            //实例化文件对象
            File file = new File("c:\student.txt");
            try {
                //定义文件输出流
                FileOutputStream fos = new FileOutputStream(file);
                //打印标题
                fos.write("姓名	语文	数学	英语
    ".getBytes());
                //循环打印学生信息
                for (Student stu : list) {
                    String info = stu.getName()+"	"+stu.getChinese()+"	"+stu.getMath()+"	"+stu.getEnglish()+"
    "; 
                    fos.write(info.getBytes());
                }
                //关闭输出流
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("文件写入完成");
        }
    }

    第2题:分析运行结果,说明原理。

    class Data {
        int val;
    }
    public class Test2 {
    
        public static void main(String[] args) {
            Data data = new Data();
            ArrayList<Data> list = new ArrayList<Data>();
    
            for (int i = 100; i < 103; i++) {
                data.val = i;
                list.add(data);
            }
    
            for (Data d : list) {
                System.out.println(d.val);
            }
        }
    
    }

    答:data对象在循环外部实例化分配了堆内存空间,并用data引用指向了这块内存空间,循环中每次修改都是同一个对象的数据,因此data对象val属性
    在三次循环后从100修改成了102,因此打印三个102。

    3、 假如我们在开发一个系统时需要对员工进行建模,员工包含 3 个属性:姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。 请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。

    class Employee{
        private int id;
        private String name;
        private float salary;
        
        public Employee(int id, String name, float salary) {
            this.id = id;
            this.name = name;
            this.salary = salary;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public float getSalary() {
            return salary;
        }
        public void setSalary(float salary) {
            this.salary = salary;
        }
        @Override
        public String toString() {
            return "Employee [id=" + id + ", name=" + name + ", salary=" + salary
                    + "]";
        }
    }
    class Manager extends Employee{
        //增加一个奖金属性
        private float bonus;
        
        public Manager(int id, String name, float salary, float bonus) {
            //调用父类的构造方法
            super(id, name, salary);
            this.bonus = bonus;
        }
    
        public float getBonus() {
            return bonus;
        }
    
        public void setBonus(float bonus) {
            this.bonus = bonus;
        }
        
    }
    public class Test3 {
        public static void main(String[] args) {
            //调用构造方法
            Manager m = new Manager(1,"zqt",10000.0f,10000.0f);
            System.out.println(m);
        }
    }

    第4题:方法中的内部类能不能访问方法中的局部变量,为什么?

    答:必须加上final关键字才能访问,由于内部类的生命周期比局部变量的生命周期要长,当局部变量被系统回收时,内部类就无法访问局部变量。而声明 成final后内部类会得到一份拷贝,即使局部变量消亡,内部类仍能获得这个不变的值。

    class Outer{
        void out(){
            final int a = 5;
            class Inner{
                void in(){
                    System.out.println(a);
                }
            }
            new Inner().in();
        }
    }
    public class Test4 {
        public static void main(String[] args) {
            new Outer().out();
        }
    }

    第5题: 已知文件a.txt文件中的内容为“bcdeadferwplkou”,请编写程序读取该文件内容,并按照自然顺序排序后输出到b.txt文件中。 即b.txt中的文件内容应为“abcd…………..”这样的顺序。

    public class Test5 {
        public static void main(String[] args) {
            //定义输入,输出文件
            File file = new File("c:\a.txt");
            File file2 = new File("c:\b.txt");
            try {
                //内存操作流
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                //文件输入,输出流
                FileInputStream fis = new FileInputStream(file);
                FileOutputStream fos = new FileOutputStream(file2);
                int len = 0;
                //byte数组临时存储数据
                byte[] b = new byte[1024];
                //循环读取数据
                while((len=fis.read(b))!=-1){
                    //写入到内存
                    baos.write(b,0,len);
                }
                String str = baos.toString();
                //关闭流
                baos.close();
                //将字符串转化为字符数组
                char[] ch = str.toCharArray();
                //调用工具类进行排序
                Arrays.sort(ch);
                //遍历每个字符
                for (char c : ch) {
                    //写入文件
                    fos.write(c);
                }
                //关闭流
                fos.close();
                System.out.println("操作完成!");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

     另一种解法

    File file1 = new File("c:\a.txt");
                File file2 = new File("c:\b.txt");
                FileInputStream fis = new FileInputStream(file1);
                FileOutputStream fos = new FileOutputStream(file2);
                byte[] b = new byte[fis.available()];
                while(fis.read(b)!=-1){
                    Arrays.sort(b);
                    fos.write(b);
                }

    第6题:编写程序,循环接收用户从键盘输入多个字符串,直到输入“end”时循环结束,并将所有已输入的字符串按字典顺序倒序打印。

    public class Test6 {
        public static void main(String[] args) {
            System.out.println("请输入多个字符串,用回车分隔,输入end结束!");
            //从键盘读入
            Scanner scan = new Scanner(System.in);
            List<String> list = new ArrayList<String>();
            String line = scan.nextLine();
            //当输入"end"时结束循环
            while(!"end".equals(line)){
                //将输入的字符串加入到集合中
                list.add(line);
                line = scan.nextLine();
            }
            //使用工具类对字符串按字典顺序排序
            Collections.sort(list);
            //将字符串序列反转
            Collections.reverse(list);
            for (String string : list) {
                System.out.println(string);
                
            }
        }
    
    }

    第7题:已知一个类,定义如下:

    package cn.himi;
    public class DemoClass {
    public void run()
    {
    System.out.println("welcome to himi!");
    } 
    }

    (1) 写一个Properties格式的配置文件,配置类的完整名称。
    (2) 写一个程序,读取这个Properties配置文件,获得类的完整名称并加载这个类,用反射 的方式运行run方法。

    public class Test7 {
        public static void main(String[] args) {
            //定义一个属性配置文件
            Properties p = new Properties();
            //添加属性
            p.setProperty("className","cn.himi.DemoClass");
            File file = new File("c:\himi.properties");
            try{
                FileOutputStream  fos = new FileOutputStream(file);
                p.store(fos, null);
                FileInputStream fis = new FileInputStream(file);
                //读取属性文件
                p.load(fis);
                //根据键得到值
                String className = p.getProperty("className");
                //实例化Class 对象
                Class<?> clazz = Class.forName(className);
                //获得方法
                Method method = clazz.getMethod("run", null);
                //调用方法
                method.invoke(clazz.newInstance(), null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    第8题:分析以下程序运行结果,说明原理。

    class MyThread extends Thread {
        public void run() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
            }
            System.out.println("B");
        }
    }
    
    public class Test8 {
        public static void main(String args[]) {
            MyThread t = new MyThread();
            t.run();
            t.start();
            System.out.println("A");
        }
    }

    答:运行结果为BAB。当实例化MyThread类后,调用run(),此时并没有开启子线程,开启线程必须调用start()方法。进入run()方法后主线程睡眠3秒后打印B,之后调用了start()方法开启了子线程,由于子线程进入run()方法后需要睡眠3秒,而主线直接往下运行,所以打印A, 3秒后子线程再打印B。

    第9题:编写一个程序,它先将键盘上输入的一个字符串转换成十进制整数,然后打印出这个十进制整数对应的二进制形式。
    这个程序要考虑输入的字符串不能转换成一个十进制整数的情况,并对转换失败的原因要区分出是数字太大,还是其中包含有非数字字符的情况。
    提示:十进制数转二进制数的方式是用这个数除以2,余数就是二进制数的最低位,接着再用得到的商作为被除数去除以2,这次得到的余数就是次低位,如此循环,
    直到被除数为0为止。其实,只要明白了打印出一个十进制数的每一位的方式(不断除以10,得到的余数就分别是个位,十位,百位),就很容易理解十进制数转
    二进制数的这种方式。

    public class Test9 {
        public static void main(String[] args) {
            System.out.println("请输入十进制整数");
            boolean flag = true;
            Scanner scan = new Scanner(System.in);
            //循环检测用户输入
            while (flag) {
                //获得用户输入数据
                String line = scan.nextLine();
                //用户输入为数字
                if (line.matches("^\d+$")) {
                    long num = Long.parseLong(line);
                    //数字超过整型最大值
                    if (num > Integer.MAX_VALUE) {
                        System.out.println("数字太大,请重新输入!");
                    } else {
                        decToBin((int) num);
                        //停止循环
                        flag = false;
                    }
                } else {
                    System.out.println("请输入数字:");
                }
            }
        }
    
        private static void decToBin(int num) {
            if(num == 0){
                System.out.println("二进制为:" + num);
            }else{
                //定义可变字符串
                StringBuffer sb = new StringBuffer();
                //循环取余
                while (num != 0) {
                    int temp = num % 2;
                    num = num / 2;
                    //将取余的结果追加到末尾
                    sb.append(temp);
                }
                //将字符串反转
                sb.reverse();
                System.out.println("二进制为:" + sb.toString());
            }
            
        }
    }

    10、 有100个人围成一个圈,从1开始报数,报到14的这个人就要退出。然后其他人重新开始,从1报数,到14退出。问:最后剩下的是100人中的第几个人?

    public class Test10 {
        public static void main(String[] args) {
            List<Integer> list = new ArrayList<Integer>();
            // 将100个人编号添加到集合
            for (int i = 1; i <= 100; i++) {
                list.add(i);
            }
            // 存放退出的人的集合
            List<Integer> kill = new ArrayList<Integer>();
            int count = 0;
            //当集合中只有一个人时退出循环
            while (list.size() > 1) {
                for (int i = 0; i< list.size(); i++) {
                    // 进入循环一次,计数器+1
                    count++;
                    // 如果报到的数是14的倍数则将其加入到退出的人的集合
                    if (count % 14 == 0) {
                        kill.add(list.get(i));
                    }
                }
                // 删除掉退出的人的集合,剩下的就是没退出的人
                list.removeAll(kill);
            }
            System.out.println("剩下的人的序号是:"+list.get(0));
        }
    }

    测试三:

    1、 定义一个交通灯枚举,包含红灯、绿灯、黄灯,需要有获得下一个灯的方法,例如:红灯获取下一个灯是绿灯,绿灯获取下一个灯是黄灯。

    //定义交通灯枚举:TrafficLights
    enum TrafficLights {
        RED {
            /* 
                定义交通灯枚举的对象红灯,并通过匿名内部类的方式复写TrafficLights枚举
                中的抽象方法getNextLight()*/
            @Override
            public TrafficLights getNextLight() {
                // TODO Auto-generated method stub
                return GREEN;
            }
        },GREEN {
            public TrafficLights getNextLight() {
                // TODO Auto-generated method stub
                return YELLOW;
            }
        },YELLOW {
            public TrafficLights getNextLight() {
                // TODO Auto-generated method stub
                return RED;
            }
        };    
        // 交通灯枚举中的抽象方法getNextLight(),作用为返回当前交通灯的下一个灯
        public abstract TrafficLights getNextLight();
    }
    public class Traffic{
        public static void main(String[] args) {
            TrafficLights green = TrafficLights.GREEN;
            System.out.println(green.getNextLight());
        }
    }

    2、 取出一个字符串中字母出现的次数。如:字符串:"abcdekka27qoq" ,输出格式为:a(2)b(1)k(2)...

    public class OtherTest4 {
        public static void main(String[] args) {
            String str = "abcdekka27qoqAAABBBDD";
            char[] chars = str.toCharArray();
            //存储26个小写字母和26个大写字母
            int[] count = new int[52];
            for (char c : chars) {
                //小写字母
                if(c>=97&&c<=122){
                    count[c-97]++;
                }else if(c>=65&&c<=90){ // 大写字母
                    count[c-65+26]++;
                }
            }
            for (int i = 0; i < count.length; i++) {
                if(count[i]>0){
                    if(i<26){   //如果大小写字母分开存就要简单点
                        System.out.print((char)(97+i)+"("+count[i]+")");
                    }else if(i<52){
                        System.out.print((char)(65+i-26)+"("+count[i]+")");
                    }
                }
            }
        }
    }

    3、 统计一个文本文件中字符出现的次数,结果存入另外的一个文本文件中。例如:

       a:21 次
     b:15 次
       c:15 次
       把:7 次
       当:9 次
       前:3 次
       ,:30 次

    public class Test3 {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            File yuan = new File("res\1.txt");                // 要统计的文本文件
            File tongji = new File("res\tongji.txt");        // 存放统计结果的文本文件
            countChar(yuan,tongji);            // 调用countChar方法,传入两个文件,统计字符
        }
    
        public static void countChar(File yuan,File tongji) {
                // 因为操作的是文本文件,所以只用字符流就够了
            FileReader fr = null;                // 字符文件读取流,因为要逐个字节读取,所以不用缓冲
            BufferedWriter fw = null;        // 字符缓冲区写入流,提高效率
                // 创建一个HashMap的对象hm,用于存放<字符,计数>的关系
            HashMap<Character,Integer> hm = new HashMap<Character,Integer>();
            char c = 0;    // 创建两个临时变量,分别为char和int类型
            int i = 0;
    
            try {        // 操作IO的方法有可能会引发IO异常,用try进行捕获
                fr = new FileReader(yuan);
                fw = new BufferedWriter(new FileWriter(tongji));
                while((i=fr.read())!=-1) {        // 当read方法返回值不为-1时,文件未到结尾,继续读取
                    c = (char) i;                    // 将int类型值强转为char类型值
                                // 如果hm中已经存在键为c的关系,获取对应的值加1后重新存入
                    if(hm.containsKey(c))    
                        hm.put(c,hm.get(c)+1);
                    else
                        hm.put(c, 1);                // 否则将键为该字符、值为1的关系存入
                }
    
                /* 对hm的Map.Entry中的关系进行遍历,将其中键和值按格式存放进文件中
                        注:由于'
    '和'
    '字符的特殊性,会在文本文件中无法显示,本来写入
                            文件时候可以做些处理,但考虑到并不确定此文件是否有被程序读取
                            的可能,所以保持原样输出,并未做进行处理。        */
                for(Map.Entry<Character, Integer> entry : hm.entrySet()) {
                    fw.write(entry.getKey()+":"+entry.getValue());        // 按格式写入到文件中
                    fw.newLine();        // 写一句加一个行分隔符
                }
            }
            catch (IOException e) {
                            // 若发生异常,则抛出RuntimeException,并设置message
                throw new RuntimeException("操作失败");
            }
            finally {
                try {
                    if(fr!=null)
                        fr.close();        // 关闭读取流
                }
                catch (IOException e) {
                    throw new RuntimeException("读取流关闭失败");    // 关闭失败抛出RuntimeException
                }
                try {
                    if(fw!=null)
                        fw.close();        // 关闭写入流
                }
                catch (IOException e) {
                    throw new RuntimeException("写入流关闭失败"); // 关闭失败抛出RuntimeException    
                }
            }
        }
    }

    4、 定义一个标准的JavaBean,名叫Person,包含属性name、age。 使用反射的方式创建一个实例、调用构造函数初始化name、age, 使用反射方式调用setName方法对名称进行设置, 不使用setAge方法直接使用反射方式对age赋值。

    /* 真实开发中,由于所有JavaBean都要存放到同一个包中,所以为了能够从其他包访问,
            就要将类修饰为公有的,而一个java文件中只能存在一个与文件名相同的公有类,
             所以将Person类与Test6的代码分离,单独存放在一个文件中。    */
    public class Person implements Serializable {
        // Person实现Serializable接口,可以被序列化,设置其序列号为1L
        private static final long serialVersionUID = 1L;
        /*
         * JavaBean中所有属性都要被私有化,Person中按照题目要求定义了name属性以及 age属性,其中name为字符串类型,age为int类型
         */
        private String name;
        private int age;
    
        // JavaBean中必须存在一个无参数的构造方法
        public Person() {
            // TODO Auto-generated constructor stub
            this("", 0); // 调用两个参数的构造方法进行初始化
        }
    
        // 有name一个参数的构造方法
        public Person(String name) {
            this(name, 0); // 调用两个参数的构造方法进行初始化
        }
    
        // 有name和age两个参数的构造方法
        public Person(String name, int age) {
            this.setName(name); // 调用setName和()setAge()方法初始化name、age
            this.setAge(age);
        }
    
        // JavaBean中所有属性都要有对应的set/get方法,可以利用eclipse自动生成
        public String getName() { // getName()方法
            return name;
        }
    
        public void setName(String name) { // setName()方法
            this.name = name;
        }
    
        public int getAge() { // getAge()方法
            return age;
        }
    
        public void setAge(int age) { // setAge()方法
            this.age = age;
        }
    
        @Override
        public String toString() {        // 覆写Object类中的toString方法
            return "Person [name=" + name + ", age=" + age + "]";
        }
    }
    public class OtherTest6 {
        public static void main(String[] args) {
            try {
                // 向Class类的静态方法forName中传入Person类的完整名称,获得Person类的字节码文件对象
                @SuppressWarnings("unchecked")
                Class<Person> clazz = (Class<Person>) Class
                        .forName("cn.cherryhimi.Person");
                // 利用person的字节码文件对象得到该类包含字符串和整型参数的构造方法
                Constructor<Person> construstor = (Constructor<Person>) clazz
                        .getConstructor(String.class, int.class);
                // 利用此构造方法初始化name和age属性
                Person p1 = construstor.newInstance("person1", 10);
    
                System.out.println(p1); // 打印p1,查看结果是否正确
                // 利用Class类的成员方法getMethod获得题目要求的setName方法,此方法具有一个String类型的参数
                Method method = clazz.getMethod("setName", String.class);
                method.invoke(p1, "cherryhimi");
    
                System.out.println(p1); // 再次打印p1对象,查看结果
    
                /*
                 * 使用Class中的成员方法getField,得到Person类的age字段; 因为JavaBean中所有成员属性都是私有的,
                 * 所以若使用Field的方法getField则会发生异常
                 */
                Field age = clazz.getDeclaredField("age");
                // 对于私有属性的访问,要先设置权限为true,否则会发生异常
                age.setAccessible(true);
                // 调用Field类中的成员方法set,对p1的age字段进行赋值
                age.set(p1, 36);
                // 打印p1,验证结果
                System.out.println(p1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    5、 把以下IP存入一个txt文件,编写程序把这些IP按数值大小,从小到大排序并打印出来。

    61.54.231.245
    61.54.231.9
    61.54.231.246
    61.54.231.48
    61.53.231.249

    public class Test5 {
        public static void main(String[] args) {
            File file = new File("c:\str.txt");
            TreeSet<String> set = new TreeSet<String>(new Comparator<String>() {
                public int compare(String str1, String str2) {
                    String[] split1 = str1.split("\.");
                    String[] split2 = str2.split("\.");
                    int sum1 = 0;
                    int sum2 = 0;
                    for(int i=0;i<4;i++){
                        sum1 += Integer.parseInt(split1[i]);
                        sum2 += Integer.parseInt(split2[i]);
                    }
                    return sum1-sum2;
                };
            });
            try {
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line;
                while((line=br.readLine())!=null){
                    set.add(line);
                }
                for (String string : set) {
                    System.out.println(string);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    }

    6.有一个ArrayList<Integer> list=new ArrayList<Integer>();将一个String类型的字符串放进集合中。 

    public class StringDemo {
        public static void main(String[] args) {
            ArrayList<Integer > list = new ArrayList<Integer>();
            Class<? extends ArrayList> clazz = list.getClass();
            try {
                Method method = clazz.getMethod("add",Object.class);
                method.invoke(list, "hello world");
                System.out.println(list.get(0));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    7.写一个ArrayList类的代理,实现和ArrayList中完全相同的功能,并可以计算每个方法运行的时间。

    public class StringDemo {
        public static void main(String[] args) {
            final ArrayList<Integer> target = new ArrayList<Integer>();
            List proxy = (List) Proxy.newProxyInstance(target.getClass()
                    .getClassLoader(), target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method,
                                Object[] args) throws Throwable {
                            long startTime = System.currentTimeMillis();
                            Thread.sleep(10);
                            Object invoke = method.invoke(target, args);
                            long endTime = System.currentTimeMillis();
                            System.out.println("方法运行的时间为:"+(endTime-startTime));
                            return invoke;
                        }
                    });
            proxy.add("hello");
            proxy.add("world");
            proxy.remove("hello");
            System.out.println(proxy.get(0));
        }
    }

    7.存在一个JavaBean,它包含以下几种可能的属性: 1:boolean/Boolean 2:int/Integer 3:String4:double/Double 属性名未知,现在要给这些属性设置默认值,以下是要求的默认值: String类型的默认值为 字符串   www.csdn.com int/Integer类型的默认值为100 boolean/Boolean类型的默认值为true double/Double的默认值为0.01D.

    只需要设置带有getXxx/isXxx/setXxx方法的属性,非JavaBean属性不设置,请用代码实现

    class Bean{
        private boolean b;
        private int i;
        private String s;
        private double d;
        public boolean isB() {
            return b;
        }
        public void setB(boolean b) {
            this.b = b;
        }
        public int getI() {
            return i;
        }
        public void setI(int i) {
            this.i = i;
        }
        public String getS() {
            return s;
        }
        public void setS(String s) {
            this.s = s;
        }
        public double getD() {
            return d;
        }
        public void setD(double d) {
            this.d = d;
        }
    }
    public class StringDemo {
    
        public static void main(String[] args) {
            
            try {
                Class<?> clazz = Class.forName("cn.cherryhimi.Bean");
                Object bean = clazz.newInstance();
                BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
                PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
                for (PropertyDescriptor p : propertyDescriptors) {
                    Class<?> type = p.getPropertyType();
                    String name = p.getName();
                    Method getMethod = p.getReadMethod();
                    Method setMethod = p.getWriteMethod();
                    if(!"class".equals(name)){
                        if(setMethod!=null){
                            if(type == Boolean.class|| type == boolean.class){
                                setMethod.invoke(bean, true);
                            }else if(type == Integer.class || type == int.class){
                                setMethod.invoke(bean, 100);
                            }else if(type == String.class){
                                setMethod.invoke(bean, "hello world");
                            }else if(type == Double.class|| type == double.class){
                                setMethod.invoke(bean, 0.01D);
                            }
                        }
                        if(getMethod!=null){
                            
                            System.out.println(type+":"+name+"="+getMethod.invoke(bean,null));
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
    }

    8、 金额转换,阿拉伯数字转换成中国传统形式。 例如:101000001010 转换为 壹仟零壹拾亿零壹仟零壹拾圆整

    public class Test8{
        private static final char[] data = { '零', '壹', '贰', '叄', '肆', '伍', '陆',
                '柒', '捌', '玖' };
        private static final char[] units = { '圆', '拾', '佰', '仟', '万', '拾', '佰',
                '仟', '亿', '拾', '佰', '仟' };
    
        public static void main(String[] args) {
            long num = 101000001010l;
            print(num);
        }
    
        private static void print(long num) {
            StringBuffer sb = new StringBuffer();
            int temp = 0;
            int count = 0;
            while (num != 0) {
                temp = (int)(num % 10);
                num = num / 10;
                sb.insert(0, units[count]);
                sb.insert(0, data[temp]);
                count++;
            }
            String str = sb.toString().replaceAll("零[拾佰仟]", "零")
                    .replaceAll("零+亿", "亿").replaceAll("零+万", "万")
                    .replaceAll("亿万", "亿").replaceAll("零+", "零").replaceAll("零圆", "圆");
            System.out.println(str);
        }
    }

    9、 将字符串中进行反转。abcde --> edcba

    public class StringDemo {
        public static void main(String[] args) {
            String str = "abcde";
            char[] chars = str.toCharArray();
            char[] newChars = new char[chars.length];
            for (int i = 0; i < chars.length; i++) {
                newChars[chars.length-i-1]=chars[i];
            }
            System.out.println(new String(newChars,0,newChars.length));
        }
    }

    10编写一个程序,获取10120的随机数,要求随机数不能重复。

    public class Test10{
        public static void main(String[] args) {
            Random rand = new Random();
            Set<Integer> set = new HashSet<Integer>();
            while(true){
                if(set.size() == 10){
                    break;
                }else{
                    int num = rand.nextInt(20)+1;
                    if(!set.contains(num)){
                        set.add(num);
                    }
                }
            }
            for (Integer integer : set) {
                System.out.println(integer);
            }
        }
    }

    11:28人买可乐喝,3个可乐瓶盖可以换一瓶可乐,那么要买多少瓶可乐,够28人喝?假如是50人,又需要买多少瓶可乐?(需写出分析思路)   分析:  定义一个变量代表瓶盖数,当瓶盖数没有到3的时候,就继续购买可乐,同时瓶盖数加1,  当瓶盖数达到3,就把瓶盖数置为1,这次就不要购买可乐。  循环28次,可以使28人都能喝到可乐。   同理,50人喝可乐一样。 

    public class Test10 {  
        public static void main(String[] args) {  
            System.out.println("28人买可乐喝,需要买:" + BuyCokes(28) + "瓶");  
            System.out.println("50人买可乐喝,需要买:" + BuyCokes(50) + "瓶");  
      
        }  
      
        // 购买可乐方法  
        public static int BuyCokes(int num) {  
            // 瓶盖数  
            int bottle_cap = 0;  
            // 需要购买总瓶数  
            int sum = 0;  
            for (int i = 0; i < num; i++) {  
                if (bottle_cap != 3) {  
                    // 购买一瓶  
                    sum++;  
                    // 同时瓶盖增加一个  
                    bottle_cap++;  
                } else if (bottle_cap == 3) {  
                    bottle_cap = 1;// 瓶盖数置为1  
                }  
            }  
            return sum;  
        }  
    }  

     12,编写三各类Ticket、SealWindow、TicketSealCenter分别代表票信息、售票窗口、售票中心。售票中心分配一定数量的票,由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程。

    public class ThreadDemo {
        public static void main(String[] args) {
            Thread t1 = new Thread(new SealWindow());
            t1.setName("1号售票窗口");
            Thread t2 = new Thread(new SealWindow());
            t2.setName("2号售票窗口");
            Thread t3 = new Thread(new SealWindow());
            t3.setName("3号售票窗口");
            Thread t4 = new Thread(new SealWindow());
            t4.setName("4号售票窗口");
            Thread t5 = new Thread(new SealWindow());
            t5.setName("5号售票窗口");
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
        }
    
    }
    
    class Ticket {
        private int id;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
    }
    
    class SealWindow implements Runnable {
        private ReentrantLock lock = new ReentrantLock();
        @Override
        public void run() {
            sellTicket();
        }
    
        public void sellTicket() {
            TicketSealCenter tsc = TicketSealCenter.getInstance();
            List<Ticket> tickets = tsc.getTickets();
            while (!tickets.isEmpty()) {
                
                lock.lock();
                // 线程拿到锁之后,需要重新判断集合是否为空,防止线程进入循环之后,拿到锁时,集合已经为空
                if (tickets.isEmpty()) {
                    // 如果集合为空,跳出循环时,需要释放锁,防止在循环里面的其它线程,因为拿不到锁而无法结束循环
                    lock.unlock();
                    break;
                }
                Iterator<Ticket> it = tickets.iterator();
                Ticket ticket = it.next();
                System.out.println(Thread.currentThread().getName() + "...."
                        + "卖了一张票,id为" + "..." + ticket.getId());
                tickets.remove(ticket);
                lock.unlock();
            }
        }
    }
    
    // 只有一个售票中心,所以把它设置成单例
    class TicketSealCenter {
        private static List<Ticket> tickets = new ArrayList<Ticket>();
        private int ticketNum = 100;
    
        private TicketSealCenter() {
            // 给每张票设置一个唯一的ID号
            setIdToTicket(tickets);
        }
    
        private static TicketSealCenter tsc = new TicketSealCenter();
    
        // 提供一个公有方法,获取售票中心对象
        public static TicketSealCenter getInstance() {
            return tsc;
        }
    
        private void setIdToTicket(List<Ticket> tickets2) {
            for (int i = 1; i <= ticketNum; i++) {
                Ticket ticket = new Ticket();
                ticket.setId(i);
                tickets.add(ticket);
            }
        }
    
        public List<Ticket> getTickets() {
            return tickets;
        }
    }

    以上代码出现卖出同一张票的问题,另一种解法

    public class Heima6 {
        class Ticket {
            public Ticket() {
                TicketSaleCenter tsc = new TicketSaleCenter(100);
                for (int i = 0; i < 5; i++) {
                    new Thread(new SaleWindow(i, tsc)).start();
                }
            }
        }
    
        class SaleWindow implements Runnable {
            TicketSaleCenter tsc;
            int num;
    
            public SaleWindow(int num, TicketSaleCenter tsc) {
                this.num = num;
                this.tsc = tsc;
            }
    
            @Override
            public void run() {
                while (!tsc.flag) {
                    tsc.sale(this);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        class TicketSaleCenter  {
            int num;
            boolean flag;
    
            public TicketSaleCenter(int num) {
                this.num = num;
            }
            public synchronized void sale(SaleWindow sw) {
                if(num>0){
                    int n = sw.num + 1;
                    System.out.println("第"+n+"号窗口卖出了第"+num+"张票");
                    num--;
                }else{
                    flag = true;
                }
            }
        }
    
        public static void main(String[] args) {
            Heima6 x = new Heima6();
            x.new Ticket();
        }
    }

     第一种解法的修改:改变同步的位置,将同步放在每次出票的地方,但是出票序列并非递增

    public class ThreadDemo {
        public static void main(String[] args) {
            Thread t1 = new Thread(new SealWindow(),"1号售票窗口");
            Thread t2 = new Thread(new SealWindow(),"2号售票窗口");
            Thread t3 = new Thread(new SealWindow(),"3号售票窗口");
            Thread t4 = new Thread(new SealWindow(),"4号售票窗口");
            Thread t5 = new Thread(new SealWindow(),"5号售票窗口");
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
        }
      
    }
      
    class Ticket {
        private int id;
      
        public int getId() {
            return id;
        }
      
        public void setId(int id) {
            this.id = id;
        }
      
    }
      
    class SealWindow implements Runnable {
        @Override
        public void run() {
            sellTicket();
        }
      
        public void sellTicket() {
            TicketSealCenter tsc = TicketSealCenter.getInstance();
            Ticket ticket = tsc.getTicket();
            while (ticket != null) {
                /*try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
                System.out.println(Thread.currentThread().getName() + "...."
                        + "卖了一张票,id为" + "..." + ticket.getId());
                ticket = tsc.getTicket();
            }
        }
    }
      
    // 只有一个售票中心,所以把它设置成单例
    class TicketSealCenter {
        private static List<Ticket> tickets = new ArrayList<Ticket>();
        private int ticketNum = 100;
      
        private TicketSealCenter() {
            // 给每张票设置一个唯一的ID号
            setIdToTicket();
        }
      
        public Ticket getTicket() {
            synchronized (tickets) {
                if(tickets.size()>0){
                    return tickets.remove(0);    
                }
                return null;
            }
        }
     
        private static TicketSealCenter tsc = new TicketSealCenter();
      
        // 提供一个公有方法,获取售票中心对象
        public static TicketSealCenter getInstance() {
            return tsc;
        }
      
        private void setIdToTicket() {
            for (int i = 1; i <= ticketNum; i++) {
                Ticket ticket = new Ticket();
                ticket.setId(i);
                tickets.add(ticket);
            }
        }
    }

     

  • 相关阅读:
    Python连接MySQL数据库之pymysql模块使用
    线程
    进程
    网络编程
    面向对象进阶
    迭代器,生成器,装饰器
    函数的基础
    Andy's First Dictionary UVA
    Stripies POJ
    Soldier and Badges CodeForces
  • 原文地址:https://www.cnblogs.com/cherryhimi/p/4081524.html
Copyright © 2011-2022 走看看