资源描述
经典编程小事例
反射与正则
1. 给一个ArrayList<Integer>集合中添加一个字符串数据,并显示
* 思路:1,获取这个集合的字节码对象 然后通过Class对象获取该集合对象.
* 2.再用Class对象获取集合的add方法对象Method
* 3.再把class对象与添加的字符串当参数传给Method的方法invoke.
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws Exception {
List<Integer> list = new ArrayList<Integer>();
Class<?> cls = list.getClass();
ArrayList<Integer> obj =(ArrayList)cls.newInstance();
Method mt = cls.getMethod("add",Object.class);
mt.invoke(obj, "String");
//obj.add("String");这样则无法编译通过
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 {
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.getProperty("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号:校验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);
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+)+";
boolean 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表示前面(.)\\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位的数据,截取成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");
System.out.println(str);
// 切割
String[] ips = str.split(" ");
// 我遍历这个字符串数组,把每个数据添加到TreeSet集合中。
TreeSet<String> ts = new TreeSet<String>();
for (String s : ips) {
ts.add(s);
// System.out.println(s);
}
//System.out.println(ts);
//最后遍历集合,把前面的0干掉
for(String s : ts){
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 BufferedReader(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())!=null) {
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 {
//定义服务器接收端口
ServerSocket 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.getOutputStream(),true);
//写入客户端数据到控制台
String str =null;
while((str=br.readLine())!=null){
pw.println(str);
//反馈回数据到客户端
pw2.println("收到");
}
ss.close();
s.close();
}
}
2. 模拟UDP协议做一个聊天工具
创建接收端与发送端
发送端设立端口,用字符缓冲流读取数据打包发送
接收端设立接收端口,接收数据包,用包的方法解析包的数据,打印到控制台
//创建发送服务端
DatagramSocket 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.length,InetAddress.getByName("fada-pc"),11111);
//打包发送
ds.send(dp);
}
ds.close();
bs.close();
// 创建接收端的服务
DatagramSocket ds = new DatagramSocket(11111);
// 用循环接收数据
while (true) {
// 定义一个容器接收数据,把这个容器传递给数据包
byte[] bye = new byte[1024];
// 调用接收方法接受数据
DatagramPacket 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和电脑名称
主要运用InetAddress类和其下面的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();
System.out.println(ip+"--------"+name);
System.out.println(id1.getHostAddress()+"------------"+id1.getHostName());
}
IO流
1. 要求获取一个程序运行的次数,如果满足5次,那么该程序退出,请给出注册的提示,并结束
思路:
* 1:定义计数器记录程序的运行次数。
* 由于这个次数如果是记录在程序中,那么程序结束,下次再开始运行,记录次数又重头开始。
* 所以,我们需要把次数记录在一个文件中。
* 2:每次我们可以从一个文件中读取一个次数,进行判断,看我们的程序是否还可以运行。
* 如果可以,就让程序继续,否则,提示要注册。
* 3:假如一个文件中,只记录一个数字没什么意义。所以,我们采用键值对的方式记录。
* 这样呢,我们就考虑到了Properties这个对象。
*/
public class Test {
public static void main(String[] args) {
try {
boolean flag = runCount();
if (!flag) {
System.out.println("请拿钱注册");
return;
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("开始玩游戏....");
System.out.println("玩游戏....");
System.out.println("结束玩游戏....");
}
// 每次读取文件,获取键值对中的值进行判断,如果大于5次就改真假值。
public static boolean runCount() throws IOException {
boolean flag = true;
// 定义一个属性文件(.properties, .ini xml)
File countFile = new File("count.properties");
// 判断文件是否存在,如果不存在就创建文件
if (!countFile.exists()) {
countFile.createNewFile();
}
// 定义我们记录数据的格式:count=值
Properties prop = new Properties();
// 把数据从文件中加载到集合中
FileInputStream fis = new FileInputStream(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 + "");
// 把集合中的数据重新写回文件
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);
}
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写入新值
*再用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 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 void 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.close();
}
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;
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的读操作。
//而Reader一次可以读取一个字符,我们得想办法一行的字符组合起来并返回。
//每次获取一个字符,组合起来,这样的话,就要求有一个容器来存储每次读到的单个字符。
//请问?用哪个容器。通过思考最终选择了StringBuilder
public class MyBufferedReader {
//private FileReader fr; //这里我不仅仅是对文件对象进行功能的增强
private Reader r;
public MyBufferedReader(Reader r){
this.r = r;
}
//模拟一次读取一行数据的方法
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();
}
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年,它会在第2年底和第4年底各生下一头母羊,第5年底死去,问一开始农场有1头母羊,N年后,农场会有多少只母羊?
public static int getSheeps(int n) {
// sheeps表示整个羊的生态圈
ArrayList<Sheep> sheeps = new ArrayList<Sheep>();
sheeps.add(new Sheep());
List<Sheep> addSheeps = new ArrayList<Sheep>();// 待添加到生态圈的新羊
List<Sheep> delSheeps = new ArrayList<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(addSheeps);
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; 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结尾的文件的路径存储到一个文本文件中
思路:
* 1:指定目录。
* 2:就可以使用递归的方式获取该目录下所有的文件对象,然后进行判断。
* 如果是以java结尾的文件,我就把该文件对象存储在集合中。
* 3:遍历集合对象,获取每个文件对象,把它的绝对路径用流的方式写入到文本文件中。
File f = new File("E:\\Java0813-毕");
ArrayList<File> array = new ArrayList<File>();
getJava(f, array);
PrintWriter pw = new PrintWriter(new FileWriter("java.txt"), true);
for (File s : array) {
System.out.println(s);
pw.println(s.getName());
}
}
private static void getJava(File f, ArrayList<File> array) {
File[] fi =f.listFiles();
for (File file:fi) {
if (file.isDirectory()) {
getJava(file,array);
}else{
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...
* 递归的出口:第一项和第二项的值都是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 getSingletonCollection(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的姓名的长度进行比较
*/
public class CompareByLength implements Comparator<Worker> {
public int compare(Worker w1, Worker w2) {
int x = 0;
if (w1.getName().length() > w2.getName().length()) {
x = 1;
} else if (w1.getName().length() == w2.getName().length()) {
x = 0;
} else if (w1.getName().length() < w2.getName().length()) {
x = -1;
}
return x;
}
}
3.在方法上应用自定义泛型
class General<T> {
// 打印T
public void show(T t) {
System.out.println(t);
}
}
public class Test2 {
public static void main(String[] args) {
General g = new General();
g.show("aaa");
g.show(new Integer(20));
print("bbb");
print(new Integer(30));
int[] in ={1,2,3};
print(in);
}
public static <Q> void print(Q q) {
System.out.println(q);
}
}
4.把集合中的字符串按照长度进行排序
//定义一个比较器
class StringCompareByLength implements Comparator<String> {
public int compare(String s1, String s2) {
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<String> hs = new TreeSet<String>(new StringCompareByLength());
hs.add("hehe");
hs.add("haha");
hs.add("abcd");
hs.add("hel");
hs.add("itcast");
hs.add("ok");
hs.add("hehe");
Iterator<String> it = hs.iterator();
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
}
}
}
05.将字符串中的数值进行排序后,生成一个字符串。"98 -1 23 0 8 14"
首先的说一下:这个字符串数值之间肯定有分隔。
1:把字符串切割成字符串
2:把切割后的字符串数组变成int数组
3:对int数组进行排序
4:把int数组转成字符串
public static void main(String[] args) {
String str = "98 -1 23 0 8 14";
// 使用切割把字符串变成了字符串数组
String[] strArray = str.split(" ");
// 定义一个int类型数组
int[] arr = new int[strArray.length];
// 把字符串数组变成int数组
展开阅读全文