设计思想-第一篇-初出茅庐
Posted 是摩卡不是抹茶呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计思想-第一篇-初出茅庐相关的知识,希望对你有一定的参考价值。
MoCha 设计思想 - 第一篇
文章内容是初学Java时,记录的内容,现在回头看感觉很有意思。
文章目录
- MoCha 设计思想 - 第一篇
- 1)、设计思想之限制接口调用的参数范围
- 2)、设计思想之利用Properties类读取配置文件
- 3)、设计思想之关于多线程中线程安全问题
- 4)、设计思想之生产者与消费者问题
- 5)、设计思想之关于文件复制和删除问题
- 6)、设计思想之在GUI中,如何善用API?(查找我们不了解的方法或类)
- 7)、设计思想之如何将JFrame窗体的坐标位置居中?
- 8)、设计思想之IO版用户登录注册
- 9)、设计思想之集合版用户登录注册
- 10)、设计思想之关于GUI设计
- 11)、设计思想之如果一个类没有构造方法
- 12)、设计思想之在IO流中如何使文本反转?
- 13)、设计思想之在ArrayList``中添加其他数据类型的数据
- 14)、设计思想之运用反射原理实现给任意对象的任意字段设置值
- 15)、设计思想之如何优雅的读取配置文件?
- 16)、设计思想之如何将一个客户端传来的信息发送给其他客户端
- 17)、设计思想之如何更快的进行文件复制?
- 18)、设计思想之工具类的编写规则
- 19)、设计思想之判断一个文件是否符合规定的某种类型
- 20)、设计思想之自定义异常类
- 21)、设计思想之web中的数据结构
- 22)、设计思想之反射与配置文件结合使用
1)、设计思想之限制接口调用的参数范围
经验:
如果我们想要将一个方法的参数入口范围变得局限点
可以将该方法的参数类型设置得小点,然后在该方法的内部调用某个功能相似的方法
这个功能相似方法的参数入口范围是比我们设定的方法参数范围大
扩展思维:
可以将我们设定的方法设置为public
将内部调用的方法设置为private
这样一来,外部类就只能通过调用我们设定的方法来对参数赋值
更大范围的方法别人是访问不到的
2)、设计思想之利用Properties类读取配置文件
/**
* 运用Properties属性集合和IO流(InputStream 、Reader都可以)
* 设计当某个模块的执行达到一定规模时,转向执行另外一个操作
*/
Properties prop = new Properties();
Reader reader = new FileReader("Count.txt");
prop.load(reader); // 既可以接收Readr , 也可以接收InputStream
String value = prop.getProperty("count");
int number = Integer.parseInt(value);
if(number > 5){
// 输出提示
} else{
// 否则执行该模块语句
}
3)、设计思想之关于多线程中线程安全问题
设置和获取线程的资源应该是同一个资源(设计思想)
那么问题来了,怎么实现呢?
实现方案:
在外界把这个资源创建出来,通过构造方法的参数将该资源传递给其他类
然后将这个资源作为锁(通常都是将资源作为构造参数传递给其他线程对象)
4)、设计思想之生产者与消费者问题
(重点)
锁对象等待后,"立即释放锁" . 等到唤醒时,从这个这地方苏醒
(重点)
锁对象唤醒并不表示可以立即执行,必须得抢CPU的时间片
boolean flag; // 默认值为false
/** 生产者 */
public synchronized void set(String name, int age){
// 如果有数据,就等待
if(this.flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 生产数据
this.name = name;
this.age = age;
this.flag = true; // 生产完后,就有数据了,所以为true
this.notify(); // 唤醒消费者
}
/** 消费者 */
public synchronized void get(){
if(!this.flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*-- 这是消费行为 -*/
System.out.println(this.name + " --- " + this.age);
this.flag = false; // 消费完后,就没有数据,所以为false
this.notify();
}
5)、设计思想之关于文件复制和删除问题
文件的复制和删除多与
增强for循环、File[] fileArray = file.listFiles();
一起使用
6)、设计思想之在GUI中,如何善用API?(查找我们不了解的方法或类)
例如:
(1)获取颜色 , 可以找Color普通类 -> Color.BLACK
(2)想要在程序中使用dos命令 , 可以找Runtime普通类
--> Runtime rt = Runtime.getRuntime()
rt.exec(String command)
(3)想要获取工具包 , 可以找Toolkit
Toolkit tk = Toolkit.getDefaultToolkit(); // 获取默认工具包 , 返回值为Toolkit类型
// 该方法返回一个Dimension对象,该对象封装了单个组件的宽和高
Dimension d = tk.getScreenSize(); // 获取屏幕的大小
/**
* 根据路径获取图片对象 , 该方法返回值类型为Image
* 注意!!!图片的路径是要全路径
*/
Image i = tk.getImage("src\\\\source\\\\休闲桌面.jpg");
jf.setIconImage(i);
(4)UIManger
7)、设计思想之如何将JFrame窗体的坐标位置居中?
/**
* 将JFrame窗体的坐标位置居中
*
* 如何将JFrame窗体的坐标位置居中呢?
* 思路:
* 1:获取JFrame窗体的宽和高
* 2:获取屏幕的宽和高
* 3:将(屏幕的宽 - JFrame窗体的宽) / 2
* (屏幕的高 - JFrame窗体的高) / 2
* 作为JFrame窗体的新坐标
*
* @param jf JFrame窗体对象
*/
public static void setLocation(JFrame jf){
// 要想获取屏幕的宽和高,就得借助Toolkit工具包
Toolkit tk = Toolkit.getDefaultToolkit();
// 获取屏幕的宽和高 , 该方法返回一个Dimension对象,该对象封装了单个组件的宽和高
Dimension d = tk.getScreenSize();
double screenWidth = d.getWidth();//该方法返回的是double
double screenHeight = d.getHeight();
/** 获取JFrame窗体的宽和高 */
int jfWidth = jf.getWidth();
int jfHeight = jf.getHeight();
/** JFrame窗体的新坐标 */
int x = (int)(screenWidth - jfWidth)/2;
int y = (int)(screenHeight - jfHeight)/2;
jf.setLocation(x, y);
}
8)、设计思想之IO版用户登录注册
关键是如何设定规则将信息存放到用户表,就怎么从用户表读取信息
/**
* 为用户进行注册
* 我们需要定义一个规则
* 用户的信息是由以下格式组成:
* userName=passWord
* @param user
*/
public static void register(User user){
BufferedWriter bw = null;
// 要注意对user表进行信息追加
try {
bw = new BufferedWriter(new FileWriter(file , true));
bw.write(user.getUserName() + "=" +user.getPassWord());
bw.newLine();
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(bw!=null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 用户登录功能
* @param name 用户名
* @param passWord 用户密码
*/
public static boolean login(String name , String passWord){
boolean flag = false;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String line = null;
while((line = br.readLine())!= null){
String[] messageS = line.split("=");
if(messageS[0].equals(name) && messageS[1].equals(passWord)){
flag = true;
break;
}
}
// 用户信息匹配,进行登录
} catch (IOException e) {
e.printStackTrace();
} finally {
if(br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return flag; // 信息不匹配,登录失败
}
9)、设计思想之集合版用户登录注册
关键是在于一开始就静态加载ArrayList<User>, 还有遍历ArrayList的形式
/** 为了让集合的对象在注册和登录时统一,于是我们将集合定义为成员变量 */
/** 为了不让外人看见,我们将存放用户信息的集合设置为private */
/** 为了能够让对象共享存放的用户信息,我们将集合设置为static */
private static ArrayList<User> list = new ArrayList<User>();
// 判断用户登录时,用户的信息是否匹配,如果不匹配就返回false
@Override
public boolean login(String name, String passWord) {
for (User user : list) {
if (user.getUserName().equals(name)
&& user.getPassWord().equals(passWord)) {
return true;
}
}
return false;
}
// 将注册的用户信息存储到集合中
@Override
public void register(User user) {
list.add(user);
}
10)、设计思想之关于GUI设计
(1)
注册控件
设置鼠标样式使用代码:
lblRegister.setCursor(new Cursor(Cursor.HAND_CURSOR)); // 可以使鼠标变成抓手
(2)"<html><u>进行注册</u><html>"可以使标签文字有下划线
(3)如何将子窗体关闭? - 子窗体要在桌面面板上, 菜单栏上添加的是MenuItem , 不是Menu
子窗体.setClosable();
(4)如何使子窗体只有一个?(以下代码在主界面中)
private JInternalFrame inFrame = null;
(在子窗体的监听事件里)
if(inFrame!=null){ //此时说明有子窗体
inFrame.dispose();
}
JInternalOper f1 = new JInternalOper();
f1.setVisable(true);
desktopPane.add(f1);
inFrame = f1;
11)、设计思想之如果一个类没有构造方法
如果一个类没有构造方法, 那么有以下情况:
(1)成员都是静态的, 如(Math 、Arrays 、Collections)
(2)单例设计模式, 如(Runtime)
(3)类中有静态方法返回该类对象(InetAddress)
class Demo{
private Demo(){}
public static Demo getXxx(){
return new Demo();
}
}
12)、设计思想之在IO流中如何使文本反转?
分析:
(1)创建输入输出流
(2)创建集合对象
(3)将读取到的数据存入到集合中
(4)倒着遍历集合
(5)关流
13)、设计思想之在ArrayList<Integer>
中添加其他数据类型的数据
/*
如果想要在ArrayList<Integer>中添加其他数据类型的数据,可以做到吗?如何实现?
通过反射原理来实现
* 使用反射原理
* (1)获得ArrayList的Class对象 - 这里已经提供了对象,所以可以直接通过对象调用getClass()
* (2)通过Class对象去获取add方法并使用
*
* 分析为什么可以通过反射原理来实现越过泛型进行添加元素
* 因为:泛型的作用主要体现在编译期间,可以有效的避免错误数据类型的添加
* 实际上,集合的add(E e)方法的参数是E类型的,也就是说在代码执行过程中
* 方法参数类型是没有什么影响的,可以放其他类型数据,String,甚至是某个类的对象
*
* 反射所做的就是从ArrayList集合对象的Class对象入手
* 获取集合的add(E e)方法来直接使用
* 效果相当于去掉泛型
*/
代码示例:
ArrayList<Integer> list = new ArrayList<Integer>();
Class c = list.getClass();
Method m = c.getDeclaredMethod("add", Object.class);
m.invoke(list , "hello");
Student stu = new Student();
m.invoke(list , stu);
System.out.println(list);
// 输出结果:
[hello, Student [name = null, age = 0, id = null]]
14)、设计思想之运用反射原理实现给任意对象的任意字段设置值
/**
* 实现给任意对象的任意字段设置值
* @param obj 含有该字段的对象
* @param name 要赋值的字段名称
* @param value 要给字段赋的值
* @throws Exception
*/
public static void setProperties(Object obj, String name , Object value) throws Exception{
// 获取Class对象
Class c = obj.getClass();
// 通过Class对象获取指定字段,因为获取到的字段有可能存在访问限制,得采取暴力访问
Field f = c.getDeclaredField(name);
f.setAccessible(true);
f.set(obj, value);
}
15)、设计思想之如何优雅的读取配置文件?
// 如何读取配置文件?
InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("properties.txt");
Properties prop = new Properties();
prop.load(is);
String driverClass = prop.getProperty("driverClass");
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String password = prop.getProperty("password");
// 配置文件在反射中的应用:
/**
* 使用反射运行配置文件内容
* 1:创建Properties属性集
* 2:将配置文件通过load()方法加载到属性集里
* 3:从属性集中获取数据
*/
Properties prop = new Properties();
FileReader fr = new FileReader("class.txt");
prop.load(fr);
// 通过属性集的键值获得对应的值
String className = prop.getProperty("className");
String MethodName = prop.getProperty("MethodName");
// 要注意配置文件里的类名路径
Class c = Class.forName(className);
Constructor con = c.getDeclaredConstructor();
con.setAccessible(true);
Object obj = con.newInstance();
Method m = c.getDeclaredMethod(MethodName);
m.setAccessible(true);
m.invoke(obj);
16)、设计思想之如何将一个客户端传来的信息发送给其他客户端
// 为了能够将客户端传送过来的信息发送给其他客户端,我们先将各个客户端存储到集合中
ArrayList<Client> clients = new ArrayList<Client>();
s = ss.accept();
Client client = new Client(s);
clients.add(client); // 将客户端添加到集合中
new Thread(client).start();
定义一个内部类实现Runnable接口
private class Client implements Runnable{...}
17)、设计思想之如何更快的进行文件复制?
(1)复制文件:
代码举例:(直接一条语句搞定)
Files.copy(Paths.get("a.txt"), new FileOutputStream("g.txt"));
(2)把集合数据写到文件
代码举例:
ArrayList<String> list = new ArrayList<String>();
list.add("杨泽锋");
list.add("小树林");
list.add("肥威");
Files.write(Paths.get("g.txt"), list, Charset.forName("GBK"));
18)、设计思想之工具类的编写规则
(1) 如果工具类中有静态方法,那么就将构造器用private或者是使用abstract来修饰
强制调用者,直接使用类名来调用工具方法(Arrays,Collections)
(2) 如果工具类中没有静态方法,那么就将工具类设计为单例模式
19)、设计思想之判断一个文件是否符合规定的某种类型
上传类型约束:{
// =====方式1:=====
private static final String ALLOWED_IMAGE_TYPE = "jpg;png;gif";
//在正式处理上传控件前,先判断文件是否符合我们想要的类型
String[] types = ALLOWED_IMAGE_TYPE.split(";"); // 因为数组不能直接判断一个元素是否包含在里面
boolean isType = Arrays.asList(types).contains(FilenameUtils.getExtension(FilenameUtils.getName(item.getName())));
// 我们先将数组转化为List集合,然后通过集合中的contains()方法来判断
if(!isType){
req.setAttribute("errorMes", "Coder,您还没有正确选择文件喔");
req.以上是关于设计思想-第一篇-初出茅庐的主要内容,如果未能解决你的问题,请参考以下文章