Day04 学习java 2020-10-1

1 篇文章 0 订阅
1 篇文章 0 订阅

学习java Day04

泛型

  • 泛型的使用可以减少代码的编写
  • 格式:通过定义(可以不用T,写别的E,V …)
  • 常用有三种泛型的使用
  • 泛型类的定义
public class Generic<T>{
	private T temp;
	public void setTemp(T temp){
		this.temp=temp;
	}
	public T getTemp(){
		return this.temp;
	}
	public void show(T param){
		System.out.println(param);
	}
}
// 使用
Generic<String> g = new Generic<String>();
g.setTemp("a");
String str = g.getTemp();
g.show("sstt");
  • 泛型方法的定义
public class Gcc{
	public <T> void show(T nn){
		System.out.println(nn);
	}
}
// 使用
new Gcc().show(12); // 传递参数时自动确定泛型的具体类型
  • 泛型接口的定义
//格式
public interface Gcc<T>{
	void show(T param);
}
// 实现类的定义  接口使用的是泛型,实现类也必须指定泛型
public class GccImpl<T> implements Gcc<T>{...}
// 接口确定了泛型的类型,实现类就不需要指定类型的了
public class GccImpl implements Gcc<String>{...}
  • 泛型通配符 <?> 用来接收任意类型的泛型 , 相当于对象中用Object obj = new xxx();任意的类
List<?> list1 = new ArrayList<String>();
List<?> list2 = new ArrayList<Double>();
// 高级使用
// extends 表示类B必须是类A及其子类
List<? extends 类A>  list = new ArrayList<类B>();
// super 表示类B必须是类A及其父类 
List<? super 类A>  list = new ArrayList<类B>();

日期类的使用

  1. Date类的使用
// 获得当前时间的日期对象
Date date = new Date();
// 参数表示距离1970/1/1 0:0:0 的毫秒值 的日期(中国为1970/1/1 8:0:0)开始,时区不同
Date date = new Date(milltime);
// 得到这个日期与1970/1/1 0:0:0 的毫秒值
date.getTime();
// 设置毫秒值
date.setTime(milltime);  
  1. SimpleDateFormat 类,对Date对象格式化,或者将字符串解析为Date对象
// 构造函数的参数是 要解析为字符串的格式 不同的字母表示不同的意义, yyyy 表示年 ...
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(date);  // 2008-10-1 10:01:00
// 还可以将指定格式的字符串转化为Date对象  不按指定格式会报出异常
String s = "2008/10/1 10:01:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date dt = sdf.parse(s);   // 会报出异常,需要抛出或者try{...}catch(){...}
System.out.println(dt)  //Wed Oct 01 10:01:00 CST 2008
  1. Calendar类 日历类
    这是一个抽象类,但有一个静态方法可以得到该类的子类对象
Calendar cal = Calendar.getInstance()   // 得到当前时间的对象
int year = cal.get(Calendar.YEAR);  // 得到年
int month= cal.get(Calendar.MONTH)+1;  // 得到月   这里的月份是0-11 所以需要手动加1才能与我们的对应
int date= cal.get(Calendar.DATE);  // 得到日
// 设置指定时间
cal.set(2020,2,1); // 这里表示的其实是 3月1日
// 得到2月有几天
// 对指定的字段进行修改
cal.add(Calendar.DATE,-1);
date= cal.get(Calendar.DATE);  // 得到 2 月的最后一天,即天数
  1. 获得当前时间的毫秒值的另一种方式
long milltime = System.currentTimeMillis();

File类 (常用的方法)

  1. 创建File类的对象:常用的3种
// 这个路径可以是不存在的
File file1 = new File("路径");
File file2 = new File(file1,"子路径");
File file3 = new File("父路径","子路径"); // 两个路径拼接得到最后的完整路径
  1. 使用File对象创建文件,目录(单级和多级)
//创建文件,只能在存在的目录中如果文件不存在则创建文件(返回true),文件存在也不创建(返回false)
file1.creatNewFile();
// 创建单级目录 例存在E:\a\b 只能创建E:\a\b\x 不能创建E:\a\b\x\xx
flie1.mkdir();
// 可以创建多级目录
flie1.mkdirs();
  1. 判断路径所在的文件和目录是否存在 :file1.exists();
  2. 判断路径所在的是文件还是目录
file1.isFile() // 判断是否是文件
file1.isDirectory() //  判断是否是目录
  1. 得到File对象的一些参数
// 此抽象路径的文件名或者目录名
String filename = file1.getName();
// 返回抽象路径的字符串形式(你在创建File对象时写的路径)
String filepath = file1.getPath();  
// 返回此抽象路径的绝对路径
String fileAbsolutePath = file1.getAbsolutePath();
  1. 如果抽象路径表示的是目录,还可以展示此目录的所有文件和目录
String[] listfiles = file1.list() // 以字符串形式返回 [aaa, bbb, d.txt, d2.txt, file]
File[] FileLists = file1.listFiles(); // 以文件对象形式返回 

IO流

** 对流的操作结束要及时关闭流**

字节流

  1. 字节流分为:字节输入流(InputStream)和字节输出流(OutputStream),因为是抽象类不能直接创建对象,需要用其子类创建对象
  2. 常用的子类有FileOutputStream和FileInputStream
  • 创建文件字节输出流对象 FileOutputStream(常用的四种创建方式)
//创建文件输出流对象 常用的有四种构造方法 第一个参数可以使用字符串或者File的对象,第二个参数表示是否追加数据,默认不追加,每次从头开始写
FileOutoutStream fos = new FileOutputStream("文件的路径字符串形式"/File file,boolean append)
  • 写数据 (有3种)
// 写入单个字节的数据
fos.write(97);
// 写入字节数组全部
fos.write(new byte[]{97,98,99,100,101});
// 写入字节数组某一部分
fos.write(new byte[]{97,98,99,100,101},1,3); // 写入{98,,99,100}
// 关闭流
fos.close()
  • 创建文件字节输入流 FileInputStream(常用的两种创建方式)
// 根据字符串创建
FileInputStream fis = new FileInputStream("文件路径字符串");
// 根据File对象创建
FileInputStream fis = new FileInputStream(File对象);
  • 读取文件数据(2种) 返回-1表示读取到文件末尾,则结束读取
// 读取单个字节
int bnum = fis.read();
// 读取一个字符数组
byte[] bytes = new byte[1024];
int len = fis.read(bytes);  // bytes 里面保存每次读取的内容,返回的len表示读取的长度(用于末尾的时候)
// 关闭流
fis.close()
  • 使用文件字节输入输出流实现文件的复制
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt");
byte[] bytes = new byte[1024];
int len;
if((len=fis.read(bytes))!=-1){
    fos.write(bytes,0,len);
}
fos.close();
fis.close();
  • 字节缓冲流(提供了缓冲区域,不必每次读取或者写入都调用系统进行处理,内部默认使用byte[8192]进行缓冲,底层还是得靠字节输入流或者字节输出流进行读写数据):BufferedInputStream,BufferedOutputStream
// 创建字节缓冲输出流对象
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("文件路径字符串"));
// 两种写入方式
bos.write(int) //写一个字节
bos.write(byte[] bytes,int off,int len); // 其实和文件字节输出流一样,其实就是其内部增加了一个byte[8192]的字节数组
// 关闭流
bos.close();
// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("文件路径字符串"));
// 读取
int data = bis.read() // 一次读取一个字节
int len = bis.read(byte[] bytes); 
// 关闭流
bis.close();

使用字节缓冲输入输出流进行文件复制

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("文件路径字符串"));
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("文件路径字符串"));
byte[] bytes = new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
	bos.write(bytes,0,len);
}
bos.close();
bis.close();

字符流

因为字符由不同数目的字节组成,如一个汉字在GBK中由2个字节组成,在UTF-8中由3个字节组成,但是第一个字节为负数,要想显示字符,显然用字节流不能实现
但是使用字符流还有确定其编码和解码的字符集应该一致
字符流=字节流+编码集,所以其底层还是靠字节流写入,需要传入字节流

  • 字符流有字符输入流(Reader)和字符输出流(Writer), 是抽象类不能直接使用
  • 常用的字符流InputStreamReader(字节到字符的桥梁)和OutputStreamWriter(字符到字节的桥梁),可以指定字符集
// 创建字符输出流,写数据(可以直接写字符串)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),"UTF-8");
osw.write("今天天气真好!");
// os.write(new char[]{'今','天','天','气','真','好','!'},0,7)
osw.close();
// 创建字符输入流,读取数据
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"UTF-8");
isr.read(); // 读取单个字符
// 读取一个字符数组
char[] chars = new char[1024];
int len = isr.read(chars);
System.out.println(new String(chars,0,len)); //今天天气真好!

字符流进行文件的复制,只能是文本文件,不能是图片,音频

InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"UTF-8");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt"),"UTF-8");
char[] chars = new char[1024];
int len;
while((len=isr.read(chars))!=-1){
	osw.write(chars,0,len);
}
osw.close();
isr.close();
  • InputStreamReader和OutputStreamWriter 分别有子类FileReader和FileWriter 设定了默认了字符集和缓冲区,如果要设置指定字符集,还是要使用InputStreamReader和OutputStreamWriter
  • 使用FileWriter和FileReader进行文件复制
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("d.txt");
int len;
char[] chars = new char[1024];
while((len=fr.read(chars))!=-1){
	fw.write(chars,0,len);
}
fw.close();
fr.close();
  • 字符缓冲流 BufferedReader和BufferedWriter
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
int len;
char[] chars = new char[1024];
while((len=br.read(chars))!=-1){
	bw.write(chars,0,len);
}
bw.close();
br.close();
  • 字符缓冲流的特有功能 BufferedReader readLine():读取一行数据(但不包括换行数据) 读到末尾返回nul ,BufferedWriter newLine(); 根据系统写入行分隔符(windows的\r\n Linux的\n)
    使用特有功能进行文件复制
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
String str;
while((str=br.readLine())!=null){
	bw.write(str);
	bw.newLine();
}
bw.close();
br.close();

特殊流 - 对象的序列化和反序列化流

  • 要想对对象使用序列化操作,对象这个类必须实现Serializable接口
// 序列化操作,将对象写到文件中
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("UserObject.txt"));
// 这里的User实现了Serializable接口
User user1 = new User(21,"x");
User user2 = new User(32,"xx");
User user3 = new User(45,"xxx");
oos.writeObject(user1);
oos.writeObject(user2);
oos.writeObject(user3);
oos.close();
//反序列化操作,将文件中保存的对象读取出来
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("UserObject.txt"));
Object o = ois.readObject();
// User重写了toString方法
System.out.println(o);
  • 如果在对象类中没有显式的定义serialVersionUID,jvm虚拟机会根据各方面自动生成(比较敏感,对类稍作修改,这个值就变了),如果文件中的serialVersionUID 和类的serialVersionUID 不一致则不能进行反序列化操作,建议自己显示设置
    **serialVersionUID 修饰符必须是static final long ** static final long serialVersionUID =42L;
  • 某个字段不想被序列化,可用transient修饰符

Properties集合

  • 使用方式和Map集合相似,但是有特有的方法,键和值只能传入字符串
Properties prop = new Properties();
prop.setProperty("001","这是001号");
prop.setProperty("002","这是002号");
prop.setProperty("003","这是003号");
Set<String> keys = prop.stringPropertyNames(); // 返回键的集合
for(String str:keys){  // 遍历
	String value = prop.getProperty(str);
	System.out.println(value);
}
  • Properties集合还可以将数据通过IO流写入和读取数据
// 写数据
Properties prop = new Properties();
prop.setProperty("001","这是001号");
prop.setProperty("002","这是002号");
prop.setProperty("003","这是003号");
// 可以用字符流和字节流进行写入或者读取,但是要一一对应,即字符流写的要用字符流读取
//prop.store(new FileOutputStream("a.txt"),"注释信息,可以写null");
prop.store(new FileWriter("a.txt"),"注释信息,可以写null");
// 读取数据
Properties prop = new Properties();
//prop.load(new FileInputStream("a.txt"));
prop.load(new FileReader("a.txt"));
System.out.println(prop);  // {001=这是001号, 002=这是002号, 003=这是003号}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值