欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【代码】Java小练习

程序员文章站 2024-03-23 21:52:58
...

来自廖雪峰JavaSE课程练习题

处理注解练习
处理注解
请根据注解:
@NotNull:检查该属性为非null
@Range:检查整型介于min~max,或者检查字符串长度介于min~max
@ZipCode:检查字符串是否全部由数字构成,且长度恰好为value
实现对Java Bean的属性值检查。如果检查未通过,抛出异常。

输出

checking [email protected] ...
Error:field name is null
Error:field latitude is out of range
Error:field password's length is not 8
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws Exception {
        City city1 = new City(null, 91, "1234567");
        checkCity(city1);
    }

    private static void checkCity(City c) throws Exception {
        System.out.println("checking " + c + " ...");
        Class cls = City.class;
        for (Field f : cls.getFields()) {
            checkField(f, c);
        }
    }

    private static void checkField(Field f, City c) throws Exception {
        if (f.isAnnotationPresent(NotNull.class)) {
            Object r = f.get(c);
            if (r == null) {
                System.out.println("Error:field " + f.getName() + " is null");
            }
        }
        if (f.isAnnotationPresent(Range.class)) {
            Range range = f.getAnnotation(Range.class);
            int n = (Integer) f.get(c);
            if (n < range.min() || n > range.max()) {
                System.out.println("Error:field " + f.getName() + " is out of range");
            }
        }
        if (f.isAnnotationPresent(ZipCode.class)) {
            ZipCode z = f.getAnnotation(ZipCode.class);
            String p = (String) f.get(c);
            if (p.length() != z.value()) {
                System.out.println("Error:field " + f.getName() + "'s length is not "+z.value());
            }
            if(!isInteger(p)){
                System.out.println("Error:field " + f.getName() + "is not Integer");
            }
        }

    }
    private static boolean isInteger(String s){
        try {
            Integer.parseInt(s);
            return true;
        }catch (NumberFormatException e){
            return false;
        }
    }
}


public class City{
    @NotNull
    public String name;

    @Range(max = 90)
    public int latitude;

    @ZipCode(value = 8)
    public String password;

    public City(String name,int latitude,String password){
        this.name = name;
        this.latitude = latitude;
        this.password = password;
    }
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotNull{

}

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Range {
    int min() default 0;
    int max() default 100;

}



import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ZipCode {
    int value() default 8;

}

Set练习
请将List的元素去重,但保留元素在List中的原始顺序,即:
[“abc”, “xyz”, “abc”, “www”, “edu”, “www”, “abc”]
去重时应该删除:
[“abc”, “xyz”, “abc”, “www”, “edu”, “www”, “abc”]
去重后的结果应该为:
[“abc”, “xyz”, “www”, “edu”]
提示:LinkedHashSet

import java.util.*;

public class Main{
    public static void main(String[] args){
        List<String> s = Arrays.asList("abc", "xyz", "abc", "www", "edu", "www", "abc");
        Set<String> set = new LinkedHashSet<>(s);
        List<String> res = new ArrayList<>(set);
        for (String i:res){
            System.out.println(i);
        }
    }
}

Stack练习
请用Stack将整数转换为十六进制字符串表示,即:
toHex(12500) => “30d4”
进制转换算法:

  1. 不断对整数除以16,得到商和余数,余数压栈
  2. 用得到的商重复步骤1
  3. 当商为0时,计算结束。将栈中的数依次弹出并组成String
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main{
    public static void main(String[] args){
        int n = 12500;
        String s = toHex(n);
        System.out.println(s);
    }
    private static String toHex(int n){
        // StringBuffer sb = new StringBuffer();
        // while (n!=0){
        //     sb.insert(0,Integer.toHexString(n%16));  //插入StringBuffer头部,再直接转String
        //     n /= 16;
        // }
        // return sb.toString();

        List<String> list = new ArrayList<>();
        while (n!=0){
            list.add(Integer.toHexString(n%16));
            n /= 16;
        }
        Collections.reverse(list); //先反转List,再用String连接
        return String.join("",list);
    }
}

File练习
请编写一个Java程序,能列出当前目录下的所有子目录和文件,并按层次打印。
例如:
输出:
IOFilePractice
.classpath
.project
bin
com
feiyangedu
sample
Main.class
src
com
feiyangedu
sample
Main.java
如果不指定参数,则使用当前目录,如果指定参数,则使用指定目录。
例如:
在Eclipse中设置命令行参数 C:\Users
输出:
Users
public
Michael
Desktop
download.txt
Documents
Music

import java.io.File;

public class Main {
    public static void main(String[] args) {
        String PATH = "D:\\廖雪峰的java教程";
        File fp = new File(PATH);
        walk(fp);  //遍历当前目录,打印所有文件和子目录
    }

    private static void walk(File fp) {
        if (fp.isDirectory()) {
            System.out.println(fp.getAbsolutePath());  //打印完整目录
            for (File subFp : fp.listFiles()) {
                walk(subFp);
            }
        } else {
            String path = fp.getAbsolutePath();
            String name = path.substring(path.lastIndexOf("\\") + 1); //打印文件名
            for (int i = 0; i < path.length() - name.length(); ++i) {
                System.out.print(" ");
            }
            System.out.println(name);
        }
    }
}

Input/Output练习
FileInputStream可以从文件读入数据,FileOutputStream可以把数据写入文件
如果我们一边从一个文件读取数据,一边把数据写入到另一个文件,就完成了文件的拷贝。
请编写一个程序,接收两个命令行参数,分别表示源文件和目标文件, 然后用InputStream/OutputStream把源文件复制到目标文件。
复制后,请检查源文件和目标文件是否相同(文件长度相同,内容相同),分别用文本文件、图片文件和zip文件测试。

import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        String in_path = "test.tar.gz";
        String out_path = "test_bak.tar.gz";
        cpFile(in_path, out_path);
    }

    private static void cpFile(String in_path, String out_path) throws IOException {
        try (InputStream in = new BufferedInputStream(new FileInputStream(in_path));
             OutputStream out = new BufferedOutputStream(new FileOutputStream(out_path))) {
            byte[] buffer = new byte[1024];
            int n;
            while ((n = in.read(buffer)) != -1) {
                out.write(buffer, 0, n);
            }
        }
    }
}

Reader/Writer练习
请编写一个程序,接收两个命令行参数,分别表示源文件和目标文件,然后用Reader/Writer把GBK编码的源文件转换为UTF-8编码的目标文件。

import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        String in_path = "test.txt";
        String out_path = "test_bak.txt";
        transFormat(in_path, out_path);
    }

    private static void transFormat(String in_path, String out_path) throws IOException {
        try (Reader reader = new InputStreamReader(new FileInputStream(in_path), "GBK");
             Writer writer = new OutputStreamWriter(new FileOutputStream(out_path), "UTF-8")) {
            int n;
            while ((n = reader.read()) != -1) {
                writer.write(n);
            }
        }
    }
}

DateTime练习
某航线从北京飞到纽约需要12小时15分钟,请根据起飞日期和时间计算到达纽约的当地日期和时间。
例如,用户输入一个标准的日期和一个标准的时间:
Departure date: 2016-12-01
Departure time: 07:50
输出到达的当地日期和时间:
Arrival date: xxxx-xx-xx
Arrival time: xx:xx

import java.time.*;

public class Main {
    public static void main(String[] args) {
        LocalDate bjDate = LocalDate.parse("2016-12-01");    //解析出发北京本地日期和时间
        LocalTime bjTime = LocalTime.parse("07:50");
        System.out.println("Departure date: " + bjDate);
        System.out.println("Departure time: " + bjTime);

        LocalDateTime bjDateTime = LocalDateTime.of(bjDate, bjTime);  //出发时北京时间
        LocalDateTime bjArrivalDateTime = bjDateTime.plusHours(12).plusMinutes(15);   //加上路程时间,到达时北京时间
        ZonedDateTime bj = bjArrivalDateTime.atZone(ZoneId.systemDefault());    //本地时间转时区时间
        ZonedDateTime ny = bj.withZoneSameInstant(ZoneId.of("America/New_York"));   //到达时纽约时间
        LocalDate nyDate = ny.toLocalDate();    //到达纽约的时区时间,转成纽约的本地日期和时间
        LocalTime nyTime = ny.toLocalTime();
        System.out.println("Arrival date: " + nyDate);
        System.out.println("Arrival time: " + nyTime);

    }
}