未来_我来
因为渴望改变,所以必须努力

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

答:方法中的内部类可以访问方法中的final修饰的局部变量, 因为final定义的变量相当于常量,该变量的生命周期也就延长了,这样就算方法撤销了,也能保证其内部类 还能访问到final类型的方法的局部变量。                           

备注:在以下程序说明的时候发现不用final修饰也是可以访问的,于是我首想到的是java新特性(我不久前刚换的jdk1.8),最后上网看后,了解了了一些,jdk1.8后局部变量默认加final的.

 

public class Test1 {
    public static void main(String[] args) {
        new Out().fun();//16
    }
}

class Out{
    final int j = 10;
    private int x = 0;
    public void fun(){
        final int k = 6;
        class In{
            public void inMethod(){
                x = k;
                System.out.println(x + j);
            }
        }
        new In().inMethod();
    }
}

 

 

第2题:一个ArrayList对象aList中存有若干个字符串元素,现欲遍历该ArrayList对象,删除其中所有值为"abc"的字符串元素,请用代码实现。

 

public class Test2 {
    public static void main(String[] args){
        //定义一个ArrayList集合
        ArrayList al = new ArrayList();
        //往集合中添加元素
        al.add("bac");
        al.add("abc");
        al.add("acb");
        al.add("abc");
        al.add("abcd");
        //打印原集合
        System.out.println(al);//[bac, abc, acb, abc, abcd]
        //调用opList方法,对集合进行操作
        List list = opList(al);
        //打印删除值为"abc"的字符串元素后的新集合
        System.out.println(list);//[bac, acb, abcd]
    }
    /**
     * 删除传入集合中所有值为"abc"的元素*/
    public static List opList(List list){    
        //遍历集合
        for(Iterator it = list.listIterator(); it.hasNext();){
            String str = (String)it.next();
            //如果元素的值为abc,则移除
            if("abc".equals(str)){
                it.remove();
            }
        }
        return list;
    }
}

 

 

第3题 :写一个方法,此方法可将obj对象中名为propertyName的属性的值设置为value.

public void setProperty(Object obj, String propertyName, Object value){}

 

public class Test3 {
    public static void main(String[] args){
        TestDemo td = new TestDemo();
        new Test3().setProperty(td, "propertyName", "itheima");
        System.out.println(td.getPropertyName());//itheima
    }
    
    //此方法可将obj对象中名为propertyName的属性的值设置为value
    public void setProperty(Object obj, String propertyName, Object value){
        try {
            //获取obj对象的.class(字节码文件)
            Class clazz = obj.getClass();
            //获取obj对象中名为propertyName的属性
            Field field = clazz.getDeclaredField(propertyName);
            //设置可以访问全部属性
            field.setAccessible(true);
            //将obj对象中的名为propertyName的属性的值设置为value
            field.set(obj, value);
        } catch (Exception e) {
            e.printStackTrace();
        }    
    }
}
/**
 * 测试类
 * */
class TestDemo{
    private String propertyName;

    public String getPropertyName() {
        return propertyName;
    }

    public void setPropertyName(String propertyName) {
        this.propertyName = propertyName;
    }

    @Override
    public String toString() {
        return "TestDemo [propertyName=" + propertyName + "]";
    }
}

 

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

 

思路:创建Stedent类,读取键盘输入的数据,并把数据封装到Student对象中

再把Student对象存入集合中,因为需要对Student对象排序,所以选用TreeSet集合最后把Set集合用流保存到本地硬盘上

 

public class Test4 {
    public static void main(String[] args) throws IOException {
        Set<Student> stus = StudentOp.getStudents();
        StudentOp.outputInf(stus);
    }
}
/**
 * 学生类  因为学生需要排序,所以使用TreeSet集合存储学生信息
 * 所以需要实现Comparable接口
 * */
class Student implements Comparable<Student> {
    private String name;
    private int cn,math,en;
    private int sum;

    Student(String name,int math,int cn,int en) {
        this.name = name;
        this.math = math;
        this.cn = cn;
        this.en = en;
        sum = math + cn + en;
    }
    //为了避免Hashset集合中出现重复元素,所以覆盖hashCode方法和equals方法
    public int hashCode() {
        //使用姓名和总分来判断是否出现重复
        return name.hashCode() + sum*23+100;

    }
    //覆盖equals方法
    public boolean equals(Object obj) {
        //判断传入的类型是否为Student类
        if(!(obj instanceof Student))
            throw new ClassCastException("传入的类型不匹配!");
        Student s = (Student)obj;
        //通过比较姓名和总分判断俩个实例是否相等
        return this.name.equals(s.name) && this.sum == s.sum;
    }
    //覆盖toString方法
    public String toString() {
        return "姓名:" + name + "    |     语文:"+ cn +"    |   数学:" + math +"    |    英语:" + en;
    }

    //get和set方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getSum() {
        return sum;
    }
    public void setSum(int sum) {
        this.sum = sum;
    }
    //重写比较器中的方法给学生类进行排序
    @Override
    public int compareTo(Student s) {
        //因为是需要按照总分从高到底的顺序进行排序,所以需要用参数中的对象和当前对象比较
        int num = new Integer(s.sum).compareTo(new Integer(this.sum));
        //如果总分相等,再根据姓名排序
        if(num == 0)
            return this.name.compareTo(s.name);
        return num;
    }
}
/**
 * 接收键盘输入的数据,并吧数据封装到Student对象中,再把student对象存入set集合中
 * */
class StudentOp {
    public static Set<Student> getStudents() {
        //接收键盘的输入的数据
        BufferedReader bufr = 
            new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        //创建一个带有泛型的set集合
        Set<Student> set  = new TreeSet<Student>();
        try {
            while((line = bufr.readLine()) != null) {
                if("over".equals(line))
                    break;
                
                String[] inf = line.split(",");
                //把键盘输入的数据封装到student对象中
                Student stu = new Student(inf[0],
                                        Integer.parseInt(inf[1]),
                                        Integer.parseInt(inf[2]),
                                        Integer.parseInt(inf[3]));    
                //把封装好的Student对象存入set集合中
                set.add(stu);
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }    finally{
            try {
                bufr.close();
            } catch (IOException e) {
                throw new RuntimeException("读取流资源释放失败");
            }
        }
        return set;
    }
    /**
     * 把set集合中的数据写到本地硬盘上
     * */
    public static void outputInf(Set<Student> set) {
        BufferedWriter bufw = null;
        try {
            //创建一个写入流对象
            bufw = new BufferedWriter(new FileWriter("E:" + File.separator + "itheimaExam" + File.separator + "test4.txt"));
            //把set集合中的数据写入到本地硬盘上
            for(Student stu : set) {
                bufw.write(stu.toString());
                bufw.write("        |总分:" + "(" + stu.getSum() + ")");
                bufw.newLine();
                bufw.flush();
            }
        } catch (IOException e) {
            throw new RuntimeException("写入文件失败");
        } finally{
            try {
                if(bufw != null){
                    bufw.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("写入流资源释放失败");
            }
        }
    }
}

 

 

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

a :  21 次

b :  15 次

c :  15 次

d :  7 次

e :  9 次

f :  3 次

g :  30 次

思路:1.将字符串转换成每一个字母,因为要对每一个字符进行操作

      2.因为字符和其对应的次数是键值对,所以定义一个map集合来存储

  3.遍历字符数组,将每一个字符作为键去查询Map集合,

    若Map集合中没有这个键,则将这个字符作为键,1作为值存入map集合中

    若map集合中的键存在当前的字符,则键该键对应的值取出,进行自增操作后重行吧该字符和进行自增后的值

    存入集合

 4.将map集合的键值按照指定格式存储到指定文件中

 

public class Test5 {
    public static void main(String[] args){
        output(stat(input()));
    }
    
    /**
     * 读取硬盘上指定文件中的数据,并转换成一个字符串
     * */
    public static String input(){
        //创建一个文件对象,从硬盘上读取文件
        File f = new File("E:" + File.separator + "itheimaExam" + File.separator + "test5.txt");
        
        //因为操作的是字符对象,且为了提高效率,用缓冲流BufferedReader
        BufferedReader br = null;
        //创建一个StringBuilder对象
        StringBuilder sb = new StringBuilder();
        try {
            br = new BufferedReader(new FileReader(f));
            String line = null;
            //去读硬盘上文件的内容
            while((line = br.readLine()) != null){
                //把文件上读取到的内容添加到StringBuilder对象里
                sb.append(line);
            }
        } catch (IOException e) {
            throw new RuntimeException("读取文件失败");
        } finally{
            if(br != null){
                try{
                    br.close();
                }catch(IOException e){
                    throw new RuntimeException("读取流资源释放失败");
                }
            }
        }
        //把StringBuileder里面的内容转换成一个字符串
        String str = sb.toString();
        return str;
    }
    
    /**
     * 统计传入字符串中字母出现的次数,并把字符作为键,次数作为值存入map集合中
     * */
    public static Map stat(String str){
        //把字符串对象转换成字符数组
        char[] cArray = str.toCharArray();
        //创建一个TreeMap对象
        Map<Character,Integer> map = new HashMap<Character,Integer>();
        
        //创建一个计数器
        int count = 0;
        //遍历字符数组
        for(char c : cArray){
            //如果字符数组不在a-z或者A-Z则返回继续遍历
            if(!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')){
                continue;
            }
            //遍历到的字符作为键,获取其对应在map集合中的值
            Integer value = map.get(c);
            
            //如果值不为空,则说明该字符已经出现过,则把该值传给计数器
            if(value != null){
                count = value;
            }
            count ++ ;
            //把新的字符数组和值重行存入map集合中
            map.put(c, count);
            //把计数器清0
            count = 0;
        }
        return map;
    }
    /**
     * 遍历map集合,并把里面的键和值按照规定的格式写到指定的文件中
     * */
    public static void output(Map map){    
        //通过enretSet()方法获取Map集合的键值对映射
        Set<Map.Entry<Character, Integer>> setEntry = map.entrySet();
        //声明一个BufferedWriter
        BufferedWriter bw = null;
        try{
            //创建一个文件对象
            File file = new File("E:" + File.separator + "itheimaExam" + File.separator + "result5.txt"); 
            bw = new BufferedWriter(new FileWriter(file));
            //获取map集合的键值并按规定的格式写入文件  
            for(Iterator<Map.Entry<Character, Integer>> it = setEntry.iterator(); it.hasNext();){
                Map.Entry<Character, Integer> mapEntry = it.next();
                bw.write(mapEntry.getKey() + ":" + mapEntry.getValue() + "次");
                bw.newLine();
                bw.flush();  
            } 
        } catch(IOException e){
            throw new RuntimeException("写入文件失败!");
        } finally {
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException("写入流资源释放失败!");
                }
            }
        }
    }
}

 

第6题:编写一个类,增加一个实例方法用于打印一条字符串。并使用反射手段创建该类的对象,并调用该对象中的方法。

 

public class Test6 {
    public static void main(String [] args) throws Exception{
        //获取类的字节码对象
        Class clazz = PrintDemo.class;
        //创建类的实例对象
        PrintDemo pt = (PrintDemo) clazz.newInstance();
        //获取对象中名为sop的方法,并调用
        clazz.getDeclaredMethod("sop", String.class).invoke(pt, "itheima");
    }    
}
/**
 * 测试类
 * */
class PrintDemo{
    //将字符串打印到控制台
    public void sop(String str){
        System.out.println(str);//itheima
    }
}

 

 

第7题:使用TCP协议写一个可以上传文件的服务器和客户端。

思路:因为时刻有客户端需要连接到服务端,所以服务端要为每一个连接进来的客户端创建一个线程

 

/**
 * 客户端
 * */
public class Test7 {
    public static void main(String[] args) {
        Socket s = null;
        FileInputStream fis = null;
        try {
            // 创建一个流套接字并将其连接到指定 IP地址的指定端口号
            s = new Socket("127.0.0.1", 8888);
            // 创建一个文件对象
            File file = new File("E:" + File.separator + "itheimaExam"
                    + File.separator + "test7_client.txt");
            // 创建一个文件输出流对象
            fis = new FileInputStream(file);
            // 获取流套接字的输出流
            OutputStream out = s.getOutputStream();

            // 向流中输出数据
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = fis.read(buf)) != -1) {
                out.write(buf, 0, len);
            }

            // 告诉服务端数据已经写完
            s.shutdownOutput();

            // 获取套接字的输入流对象
            InputStream in = s.getInputStream();

            // 获取服务端的反馈信息,并打印到控制台
            byte[] bufIn = new byte[1024];
            int num = in.read(bufIn);
            System.out.println(new String(bufIn, 0, num));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("输入流资源释放失败");
            } finally {
                try {
                    if (s != null) {
                        s.close();
                    }
                } catch (IOException e) {
                    throw new RuntimeException("客户端关闭失败");
                }

            }
        }
    }
}
/**
 * 服务端线程类
 * */
class TcpClient implements Runnable {
    private Socket s;

    // 创建服务端类的构造器,在生成服务端对象时传入一个端点(套接字);
    TcpClient(Socket s) {
        this.s = s;
    }

    public void run() {
        // 为了避免客户端上传重名的文件,创建一个计数器,有重名则在其名字后加上计数器中存储的数再存入
        int count = 1;

        // 获取连接进来客户端的的ip
        String ip = s.getInetAddress().getHostAddress();
        try {
            // 当有客户端连接进来,在控制台打印其ip
            System.out.println(ip + "....connected");
            // 获取连接进来客户端的输入流
            InputStream in = s.getInputStream();
            // 创建一个文件对象
            File file = new File("E:" + File.separator + "itheimaExam"
                    + File.separator + "test7_server.txt");
            // 若果客户端上传与服务端重名的文件,则在其名字后面按上传的顺序加上数字
            while (file.exists())
                file = new File("E:" + File.separator + "itheimaExam"
                        + File.separator + "test7_server" + count++ + ".txt");
            // 创建文件输出流对象
            FileOutputStream fos = new FileOutputStream(file);

            byte[] buf = new byte[1024];
            // 把客户单传进来的文件输出到本地硬盘上
            int len = 0;
            while ((len = in.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
            // 获取连接进来的客户端输出流对象
            OutputStream out = s.getOutputStream();
            // 给客户端回复应答信息
            out.write("上传成功".getBytes());
            // 关闭流对象
            fos.close();
            // 关闭客户端对象
            s.close();
        } catch (Exception e) {
            throw new RuntimeException("文件上传失败");
        }
    }
}
/**
 * 服务端
 * */
class TcpServer {
    public static void main(String[] args) {
        // 创建服务端的端点(套接字)
        ServerSocket ss;
        try {
            // 创建服务端的端点(套接字),并绑定到指定的本地端口上
            ss = new ServerSocket(8888);
            while (true) {
                // 获取连接进来的客户端对象
                Socket s = ss.accept();
                // 开启服务端线程
                new Thread(new TcpClient(s)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

 

第8题:编写一个程序,它先将键盘上输入的一个字符串转换成十进制整数,然后打印出这个十进制整数对应的二进制形式。

这个程序要考虑输入的字符串不能转换成一个十进制整数的情况,并对转换失败的原因要区分出是数字太大,还是其中包含有非数字字符的情况。

提示:十进制数转二进制数的方式是用这个数除以2,余数就是二进制数的最低位,接着再用得到的商作为被除数去除以2,这次得到的余数就是次低位,如此循环,直到被除数为0为止。

其实,只要明白了打印出一个十进制数的每一位的方式(不断除以10,得到的余数就分别是个位,十位,百位),就很容易理解十进制数转二进制数的这种方式。

 

public class Test8 {
    public static void main(String[] args) {
        test();
    }
    public static void test(){
        //定义俩个int变量,分别表示键盘上获取的数字和余数
        int num = 0, mod;

        System.out.println("请输入:");
        //创建一个字符缓冲流对象用于接收键盘输入的字符
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        String str = null;
        try {
            //从键盘上读取一行数据
            str = br.readLine();
            //把键盘上读取到的数据转换成字符数组
            char[] ch = str.toCharArray();
            //判断是否存在非数字的字符
            for (char c : ch) {
                if (!Character.isDigit(c)) {
                    System.out.println("输入的字符有非数字字符!程序退出");
                    return ;
                }        
            } 
        }catch (IOException e) {
            e.printStackTrace();
        }
        //把字符串转换成整形数
        num = Integer.parseInt(str);
        //判断数字是否超出范围
        if(num > Integer.MAX_VALUE){
            System.out.println("数字超出范围");
            return ;
        }
        
        //定义一个字符串对象,用于把每次的余数串接起来
        String s = "";
        //不断用二除,直到除不开,再把余数倒置
        while (num != 0) {
            mod = num % 2;
            num = num / 2;
            s = mod + s;
        }
        //把最终的二进制数打印到控制台
        System.out.println(s);
    }
}
请输入:
100
1100100

 

 

 

第9题:金额转换,阿拉伯数字转换成中国传统形式。

例如:101000001010   转换为   壹仟零壹拾亿零壹仟零壹拾圆整

 

public class Test9 {
    public static void main(String[] args){
        new Switch().switchNum(1234);//壹仟贰佰叁拾肆圆整
    }
}
class Switch{
    //构建汉字的字符数组
    private char[] chineseNum = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };
    private char[] chinese = {'圆', '拾', '佰', '仟'};
    public void switchNum(int number){
        int qian,bai,shi,ge;
        //分别取千位,百位,十位,个位
        qian = number / 1000;
        bai = (number % 1000) / 100;
        shi = (number % 100) /10;
        ge = number % 10;
        //把取到的各位到字符数组中查找各自对应的汉字
        char[] newChar = {chineseNum[qian], chinese[3], chineseNum[bai], chinese[2],chineseNum[shi],chinese[1],chineseNum[ge],chinese[0]};
        //打印输出
        for(char c : newChar){
            System.out.print(c);
        }
        System.out.println("整");
    }
}

 

 

第10题:28人买可乐喝,3个可乐瓶盖可以换一瓶可乐,那么要买多少瓶可乐,够28人喝?假如是50人,又需要买多少瓶可乐?(需写出分析思路)

结果:经本程序运行:28个人需要19瓶可乐,50个人需要34瓶可乐

思路:可乐可分为俩类,1:花钱买的,2:瓶盖换的,而最后需要输出的是花钱买的可乐数量

 最终不变的原则是要为每一个人分一瓶可乐,不管这瓶可乐是花钱买的还是瓶盖换的

所以,利用for循环遍历每一个人,for循环中为当前的人分一瓶可乐即可

如果瓶盖数量不够三个,则为当前遍历到的那个人买一瓶可乐,则花钱买的可乐总数加1,相应的瓶盖总数也加1。

如果瓶盖的数量够三个了,则用着三个瓶盖为当前遍历的人换一瓶可乐,这样,花钱买的可乐数量不增加,瓶盖数量变为1个

 

public class Test10 {
    public static void main(String[] args) {
        System.out.println("需要买" + cokeNum(50) + "瓶");//需要买34瓶
    }
    
    public static int cokeNum(int personNum){
        //定义一个变量bCap表示瓶盖数量
        int bCap = 0;
        //cokeSum表示需要可乐的总数
        int cokeSum = 0;
        //遍历当前的每一个人
        for(int i = 0; i < personNum; i++){
            //瓶盖数量不为3
            if(bCap != 3){
                //花钱买的可乐数量加1
                cokeSum++;
                //瓶盖数量加1
                bCap ++;
            }
            //瓶盖数量够三个了
            else if(bCap == 3){
                //用三个瓶盖为当前的人换一瓶可乐,则瓶盖数量变为1
                bCap = 1;
            }
        }
        return cokeSum;
    }
}
posted on 2018-03-08 23:12  未来_我来  阅读(248)  评论(0编辑  收藏  举报

2 3
4