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);
        }
    }
}

 

原文地址:https://www.cnblogs.com/cherryhimi/p/4081524.html