【代码】Java小练习
处理注解练习
处理注解
请根据注解:
@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”
进制转换算法:
- 不断对整数除以16,得到商和余数,余数压栈
- 用得到的商重复步骤1
- 当商为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);
}
}
下一篇: SpringMVC中四种日期格式的转换