1、经典编程小事例
反射与正则
1. 给一个ArrayList
2、ic void main(String[] args) throws Exception {
List
3、过 System.out.println(obj); } } 2. 通过配置文件运行类中的方法 import java.io.FileInputStream; import java.lang.reflect.Method; import java.util.Properties; /* * 思路: * 1,先将文件写入字节流,然后将字节流写入Properties集合中 * 2,通过getProperties方法获取方法名和类名 * 3,再通过类名获取其class对象 * 4.通过对象和方法名获取其方法 */ public class Test
4、{ public static void main(String[] args) throws Exception{ FileInputStream file = new FileInputStream("Show.txt"); Properties pro = new Properties(); pro.load(file); file.close(); //通过键值对获取对应的类名和方法名 String className = pro.getProperty("className"); String methodName= pro.getPrope
5、rty("methodName"); //通过反射获得字节码对象和方法对象 Class> cls = Class.forName(className); Object obj =cls.newInstance(); Method mt = cls.getMethod(methodName,null);//方法一定要公用public //如果是getDeclaredMethod,则也可以获取非公有方法 //如果方法私用,那么要先暴力破解:mt.setAccessible(true); mt.invoke(obj,null); } } 3.随即输入QQ号:
6、校验QQ号码:不能以0开头 是5-15位的数字 import java.util.Scanner; * * 思路:用正则定义规范,再用String类的匹配方法match方法判断时否正确 public class Test { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String qq = sc.nextLine(); String segex ="[^0][0-9]{4,14}"; boolean flag= qq.matches(segex
7、); if (flag) { System.out.println(qq); }else{ System.out.println("输入格式错误"); } 4. 邮件校验 //String regex = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]+(\\.[a-zA-Z_0-9]+)+"; //用\w改写规则\w表示:单词字符:[a-zA-Z_0-9] //反斜杠\\的用法:当在字符串中,\表示转义,所以要表示明确意思要用两个反斜杠 String regex = "\\w+@\\w+(\\.\\w+)+"; boolea
8、n flag = eamil.matches(regex); System.out.println(flag); 5.将字符串还原成:“我要学编程”。如:我...我.要.... String s = "我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程"; String regex = "\\.+";//先把点去掉 s=s.replaceAll(regex, ""); System.out.println(s); s=s.replaceAll("(.)\\1+", "$1");//再去叠词,注意:这里$1表示前面
9、)\\1内的值,也就是任意值.()是组意思 System.out.println(s); 6.能将这些ip地址排序。按照地址段数值从小到大排序。 "192.168.3.23 202.10.34.2 3.3.3.3 127.0.0.1 80.12.23.34" 思路: * ip地址都是字符串,所有字符串排序,用TreeSet。 * 如果用TreeSet现在存在每个ip地址,就会有问题。因为有部分ip没有满足三位。 * 这样比较是有问题的, 所有,我们采取补位的方式。 * 1:先给每个ip地址的每一个位在前面补2个0。 * 2:把超出3位的数据,截取成
10、3位。 */ public class Test { public static void main(String[] args) { String str = "192.168.3.23 202.10.34.2 3.3.3.3 127.0.0.1 80.12.23.34"; // 先补2个0 str = str.replaceAll("(\\d+)", "00$1"); System.out.println(str); // 去除超出3位的前面的0 str = str.replaceAll("0*(\\d{3})", "$1"); Sys
11、tem.out.println(str);
// 切割
String[] ips = str.split(" ");
// 我遍历这个字符串数组,把每个数据添加到TreeSet集合中。
TreeSet
12、 s = s.replaceAll("0*(\\d+)", "$1"); System.out.println(s); } } } 网络编程: 1.模拟Tcp协议的传输过程 */ public class Test { public static void main(String[] args) throws IOException { //定义客户端端口 Socket s = new Socket("192.168.1.111",10086); //定义读取键盘输入的流 BufferedReader br = new Bu
13、fferedReader(new InputStreamReader(System.in)); OutputStream in = s.getOutputStream(); PrintWriter pw = new PrintWriter(in,true); //定义读取服务器的字符流 BufferedReader br1 = new BufferedReader(new InputStreamReader(s.getInputStream())); String s1=null; //写入服务器 while((s1=br.readLine())!=n
14、ull) { if ("over".equals(s1)){ break; } pw.println(s1); //读取服务器写入的数据 String s3= br1.readLine(); System.out.println(s3); } pw.close(); br.close(); s.close(); } } 服务器端 public static void main(String[] args) throws IOException { //定义服务器接收端口 ServerSo
15、cket ss = new ServerSocket(10086); //或取服务器Socket接口 Socket s = ss.accept(); //获取读取客户端的流 BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); //定义输出客户端数据的流 PrintWriter pw=new PrintWriter(System.out,true); //获取反馈输出客户端的流 PrintWriter pw2=new PrintWriter(s.get
16、OutputStream(),true); //写入客户端数据到控制台 String str =null; while((str=br.readLine())!=null){ pw.println(str); //反馈回数据到客户端 pw2.println("收到"); } ss.close(); s.close(); } } 2. 模拟UDP协议做一个聊天工具 创建接收端与发送端 发送端设立端口,用字符缓冲流读取数据打包发送 接收端设立接收端口,接收数据包,用包的方法解析包的数据,打印到控制台 //创建发送服务端 Datagra
17、mSocket ds = new DatagramSocket(); // 创建键盘录入对象,并用转换流进行转换后高效处理 BufferedReader bs= new BufferedReader(new InputStreamReader(System.in)); String s =null; while((s=bs.readLine())!=null){ // 把每一行的数据进行封装 byte[] bye =s.getBytes(); DatagramPacket dp = new DatagramPacket(bye,bye.le
18、ngth,InetAddress.getByName("fada-pc"),11111); //打包发送 ds.send(dp); } ds.close(); bs.close(); // 创建接收端的服务 DatagramSocket ds = new DatagramSocket(11111); // 用循环接收数据 while (true) { // 定义一个容器接收数据,把这个容器传递给数据包 byte[] bye = new byte[1024]; // 调用接收方法接受数据 Datagr
19、amPacket dp = new DatagramPacket(bye, bye.length); ds.receive(dp); // 解析数据 String ip = dp.getAddress().getHostAddress(); String text = new String(dp.getData(), 0, dp.getLength()); // 打印数据 System.out.println(ip + "----" + text); } 3. 如何通过主机q或IP文本,获取IP和电脑名称 主要运用InetAddre
20、ss类和其下面的getByName getHostAdddress getHostName方法 public static void main(String[] args)throws UnknownHostException { InetAddress id1 = InetAddress.getByName("fada-pc"); InetAddress id = InetAddress.getByName("192.168.1.111"); String ip = id.getHostAddress(); String name = id.getHostName
21、); System.out.println(ip+"--------"+name); System.out.println(id1.getHostAddress()+"------------"+id1.getHostName()); } IO流 1. 要求获取一个程序运行的次数,如果满足5次,那么该程序退出,请给出注册的提示,并结束 思路: * 1:定义计数器记录程序的运行次数。 * 由于这个次数如果是记录在程序中,那么程序结束,下次再开始运行,记录次数又重头开始。 * 所以,我们需要把次数记录在一个文件中。 * 2:每次我们可以从一个文件
22、中读取一个次数,进行判断,看我们的程序是否还可以运行。 * 如果可以,就让程序继续,否则,提示要注册。 * 3:假如一个文件中,只记录一个数字没什么意义。所以,我们采用键值对的方式记录。 * 这样呢,我们就考虑到了Properties这个对象。 */ public class Test { public static void main(String[] args) { try { boolean flag = runCount(); if (!flag) { System.out.println("请拿钱注册"); r
23、eturn; } } catch (IOException e) { e.printStackTrace(); } System.out.println("开始玩游戏...."); System.out.println("玩游戏...."); System.out.println("结束玩游戏...."); } // 每次读取文件,获取键值对中的值进行判断,如果大于5次就改真假值。 public static boolean runCount() throws IOException { boolean flag = true;
24、 // 定义一个属性文件(.properties, .ini xml) File countFile = new File("count.properties"); // 判断文件是否存在,如果不存在就创建文件 if (!countFile.exists()) { countFile.createNewFile(); } // 定义我们记录数据的格式:count=值 Properties prop = new Properties(); // 把数据从文件中加载到集合中 FileInputStream fis = new Fi
25、leInputStream(countFile); prop.load(fis); fis.close(); // 通过键获取值 int num = 0; String value = prop.getProperty("count"); if (value != null) { num = Integer.parseInt(value); if (num >= 5) { flag = false; } } num++; // 设置值 prop.setProperty("count", num + "
26、"); // 把集合中的数据重新写回文件 FileOutputStream fos = new FileOutputStream(countFile); prop.store(fos, null); fos.close(); return flag; } } 2.实现一个包装类,让读出的每一行自动加上行号和:号 public class Test2 extends BufferedReader { private int lineNumber; public Test2(Reader r) { super(r); }
27、 public String myReadLine() throws IOException { lineNumber++; if (super.readLine()!=null) { return lineNumber+":"+super.readLine(); }else{ return null; } } } 3.*需求:把Properties.txt中键为count的值改为100 *读出到Properties集合--用load()方法 *再从转化成set集合遍历出count键,再用getProperty写入新值
28、 *再用list或store方法写放到文件中*/ public class Test { public static void main(String[] args) throws IOException { FileInputStream fs = new FileInputStream("Properties.txt"); Properties pp = new Properties(); pp.load(fs); fs.close(); System.out.println(pp); Set set =pp.keySet(); Set
29、set1 =pp.stringPropertyNames(); for (Object obj:set) { String s =(String)obj; if(s.equals("count")){ pp.setProperty(s, 100+""); } } PrintWriter pw = new PrintWriter(new FileWriter("Properties.txt"),true); pp.list(pw); pw.close(); } 4.键盘输入转大写在控制台显示 public static voi
30、d main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter pw = new PrintWriter(System.out,true); String line = null; while((line=br.readLine())!=null){ pw.println(line.toUpperCase()); } br.close(); pw.cl
31、ose(); } 5.用字符缓冲流复制一张图片并记算花费时间. public static void main(String[] args) throws IOException { BufferedInputStream br = new BufferedInputStream(new FileInputStream("c:\\纳木错.jpg")); BufferedOutputStream pw = new BufferedOutputStream(new FileOutputStream("D:\\纳木错.jpg")); int line=0;
32、long l1 =System.currentTimeMillis(); byte[] bye = new byte[1024]; while((line=br.read(bye))!=-1){ pw.write(bye); pw.flush(); } long l2 =System.currentTimeMillis(); System.out.println(l2-l1); br.close(); pw.close(); 6. 自己模拟BufferedReader对象 //思路:我们现在其实底层调用的还是Reader的读操作。
33、 //而Reader一次可以读取一个字符,我们得想办法一行的字符组合起来并返回。 //每次获取一个字符,组合起来,这样的话,就要求有一个容器来存储每次读到的单个字符。 //请问?用哪个容器。通过思考最终选择了StringBuilder public class MyBufferedReader { //private FileReader fr; //这里我不仅仅是对文件对象进行功能的增强 private Reader r; public MyBufferedReader(Reader r){ this.r = r; } //模拟一次读取一行数据的方
34、法 public String myReadLine() throws IOException{ StringBuilder sb = new StringBuilder(); //读取字符数据怎么判断是一行结束呢?在windows中是\r\n int ch = 0; while((ch=r.read())!=-1){ //如果是\r则继续读取一个字符,看是不是\n如果是就把这个sb转成字符串返回。 if(ch=='\r'){ continue; } if(ch=='\n'){ return sb.toString
35、); } else{ sb.append((char)ch);//如果不是\r\n数据,就把数据添加到sb上。 } } //假如文本文件中的数据最后没有换行,可以采用这种方式解决读不到最后一行的问题 if(sb.length()>0){ return sb.toString(); } return null; } //模拟关闭方法 public void myClose() throws IOException{ r.close(); } } 递归: 1.一头母羊的寿命是5年,它会在第
36、2年底和第4年底各生下一头母羊,第5年底死去,问一开始农场有1头母羊,N年后,农场会有多少只母羊?
public static int getSheeps(int n) {
// sheeps表示整个羊的生态圈
ArrayList
37、Sheep>();// 待从生态圈删除的羊 for (int i = 1; i <= n; i++) { for (Sheep s : sheeps) { s.age++; if (s.age == 2 || s.age == 4) {// 羊仍存活 addSheeps.add(new Sheep()); } else if (s.age == 5) { // 羊死亡,加入删除列表delSheeps中,等待删除 delSheeps.add(s); } } sheeps.addAll(addShee
38、ps); sheeps.removeAll(delSheeps); addSheeps.clear();// 清空addSheeps delSheeps.clear();// 清空待删除列表中的元素 } return sheeps.size(); // 最后总羊数即羊生态圈中的羊数目 } } 递归: public static int get(int year) { int num=1; //The initial sheep number for(int i=1; i<=year;
39、 i++){ if(i==2){ num+=get(year-2); }else if(i==4){ num+=get(year-4); }else if(i==5){ num--; } } return num; } 2.将某个目录(含子目录和文件的)下所有的以java结尾的文件的路径存储到一个文本文件中 思路:
40、
* 1:指定目录。
* 2:就可以使用递归的方式获取该目录下所有的文件对象,然后进行判断。
* 如果是以java结尾的文件,我就把该文件对象存储在集合中。
* 3:遍历集合对象,获取每个文件对象,把它的绝对路径用流的方式写入到文本文件中。
File f = new File("E:\\Java0813-毕");
ArrayList
41、"java.txt"), true);
for (File s : array) {
System.out.println(s);
pw.println(s.getName());
}
}
private static void getJava(File f, ArrayList
42、if (file.getName().endsWith(".java")) { array.add(file); } } 3.* 求5的阶乘。 递归的问题: * 1:递归的次数不能过多。 * 2:递归必须有结束条件。递归出口。 * 5*4*3*2*1 public static int getTotal(int m){ //m=5 if(m==1){ return 1; } else{ return m*getTotal(m-1); 4.斐波纳契数列:* 1,1,2,3,5,8,13,21..
43、 * 递归的出口:第一项和第二项的值都是1 a b * 递归的表达式:第三项开始:是前两项之和 a+b */ public static int getFib(int m){ if(m==1 || m==2){ return 1; } else{ return getFib(m-1)+getFib(m-2); } } 集合: 1.去除ArrayList集合中的重复元素。 思路:用contains方法去判断,定义一个新集合去装, public static ArrayList getSingletonCollecti
44、on(ArrayList array) { ArrayList al = new ArrayList(); for (int x = 0; x < array.size(); x++) { String str = (String) array.get(x); //判断al中是否包含某个元素,如果不包含,则把元素加入al. if (!al.contains(str)) { al.add(str); } } return al; } } 2.自定义比较器,实现按照Worker的姓名的长度进行比较 */ pub
45、lic class CompareByLength implements Comparator
46、getName().length()) {
x = -1;
}
return x;
}
}
3.在方法上应用自定义泛型
class General
47、0));
print("bbb");
print(new Integer(30));
int[] in ={1,2,3};
print(in);
}
public static void print(Q q) {
System.out.println(q);
}
}
4.把集合中的字符串按照长度进行排序
//定义一个比较器
class StringCompareByLength implements Comparator
48、 int num = s1.length()-s2.length();
//int compareTo 按字典顺序比较两个字符串。相等返回0
return num==0?pareTo(s2):num;
}
}
public class HashSetTest {
public static void main(String[] args) {
TreeSet
49、);
hs.add("abcd");
hs.add("hel");
hs.add("itcast");
hs.add("ok");
hs.add("hehe");
Iterator






