一:泛型
泛型:java中的参数化类型被称为泛型。以集合为例,集合可以使用泛型限制被添加元素的数据类型,如果将不符合指定数据类型的元素添加到集合内,编译就会报错。例如,Set<String>表明Set集合只能保存字符串类型的对象。
1、在集合中使用泛型。
/**
* @Author: 随心的小新
* @Date: 2019/8/21 10:24
* 在集合中使用泛型
* 在实例化集合类时,可以指明具体的泛型类型。
* 泛型的类型必须是个类。
* 如果实例化时,没有指明泛型的类型,默认类型为Object类型。
*/
public class GenericTest {
// 在集合中使用泛型,以ArrayList为例
public void test1(){
ArrayList<Integer>arrayList = new ArrayList<> ( );
arrayList.add ( 1 );
arrayList.add ( 123 );
// 编译时,就会进行类型检查,保证数据的安全
// arrayList.add ( "tom" );
// 一:方式一:
for (Integer sc : arrayList){
// 避免了强转操作
int score = sc;
System.out.println(score) ;
}
// 方式二:
Iterator<Integer> iterator = arrayList.iterator ();
while (iterator.hasNext ()){
int score1=iterator.next ();
System.out.println (score1);
}
}
// 在集合中使用泛型,以HashMap为例
public void test2(){
Map<String,Integer> map = new HashMap<String, Integer> ( );
map.put ( "tom",12 );
map.put ( "jenny",13 );
// 泛型的嵌套
Set<Map.Entry<String,Integer>> entrySet = map.entrySet ();
Iterator<Map.Entry<String, Integer>> iterator = entrySet.iterator ();
while (iterator.hasNext ()){
Map.Entry<String, Integer> next = iterator.next ();
String key = next.getKey ();
Integer value = next.getValue ();
System.out.println (key+"-------"+value);
}
}
}
2、自定义一个泛型类
/**
* @Author: 随心的小新
* @Date: 2019/8/21 10:50
* 自定义泛型类
*/
public class Order <T>{
String orderName;
int orderId;
// 类的内部可以使用类的泛型
T orderT;
public Order(){
}
public Order(String orderName,int orderId,T orderT){
this.orderId = orderId;
this.orderName = orderName;
this.orderT = orderT;
}
public T getOrderT(){
return orderT;
}
public void setOrderT(T orderT){
this.orderT = orderT;
}
@Override
public String toString() {
return "Order{" +
"orderName='" + orderName + '\'' +
", orderId=" + orderId +
", orderT=" + orderT +
'}';
}
}
//测试类
public class OrderTest {
public void test1(){
Order<String>order = new Order<String> ( "11",11,"111" );
order.setOrderT ( "12" );
System.out.println (order);
}
public static void main(String[] args) {
OrderTest orderTest = new OrderTest ();
orderTest.test1 ();
}
}
3、实例
/**
* @Author: 随心的小新
* @Date: 2019/5/5 14:32
*/
public class Ranking {
public static void main(String[] args) {
String[] teams = {
"伊朗","韩国","日本","澳大利亚","卡塔尔","沙特阿拉伯","乌兹别克斯坦","阿拉伯","中国","叙利亚"
};
//创建Map 集合对象
Map<Integer,String> map = new HashMap<Integer, String> ( );
for (int i =0;i<teams.length;i++){
map.put ( i+1,teams[i] );
}
Scanner sc = new Scanner ( System.in );
System.out.println ("依据输入的名次查询亚足联排名前十的足球队:");
try {
int number = sc.nextInt ();
if (number>0&&number<+10){
System.out.println ("亚足联排名第"+number+"男足国家队是"+map.get ( number )+"");
sc.close ();
}else {
System.out.println ("输入错误");
}
} catch (InputMismatchException e){
System.out.println ("输入错误!只能输入1-10中的某一个整数。");
}
}
}
4、通配符的使用
public void test3(){
// 通配符的使用:?
// 对于list<?>就不能向其内部添加数据了,可以添加null,但是可以读取数据
List<Object> list1 = null;
List<String>list2 = null;
List<?>list = null;
list=list1;
list=list2;
print ( list1 );
print ( list2 );
}
public void print(List<?> list){
Iterator<?> iterator = list.iterator ();
while (iterator.hasNext ()){
Object object = iterator.next ();
System.out.println (object);
}
}
二、IO流
1、File类的使用
/**
* @Author: 随心的小新
* @Date: 2019/8/21 14:35
* 1、File类的一个对象,代表一个文件或一个文件目录(俗称文件夹)
* 2、File类声明在java.io包下
*/
public class FileTest {
/**
* 1、相对路径:相较于某个路径下,指明的路径
* 2、绝对路径:包含在盘符在内的文件或文件目录的路径
* 路径中的每级目录之间需要用一个路径分隔符隔开。
* 其中:Windows和DOS系统默认使用"\"来表示;
* UNIX和URL使用"/"来表示;
*/
public void test1() throws IOException {
File file = new File ( "hello.txt" );//相对路径,相对于当前model
File file2 = new File ( "D:\\io\\io1" );//文件目录的创建
// File file1 = new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\file类的实例化" );//绝对路径
if (!file.exists ()){
file.createNewFile ();
System.out.println ("创建成功");
}else {
file.delete ();
System.out.println ("删除成功");
}
}
public static void main(String[] args) {
FileTest fileTest = new FileTest ();
try {
fileTest.test1 ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
2、流的分类
①:按照操作数据单位不同分为:字节流、字符流;
②:按照数据流的流向的不同分为:输入流、输出流;
③:按照流的角色的不同分为:节点流、处理流;
2.1、字符流的操作
public class FileReaderWriterTest {
// 将该文件夹下的文件hello.txt的内容读入程序中,并输出到控制台
public void testFileReader() throws IOException {
// 1、实例化File类对象,指明操作的 文件
File file = new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" );
// 2、提供具体的流
FileReader fr = new FileReader ( file );
// 3、数据的读入
// read ():返回读入的一个字符,如果达到文件末尾,则返回-1。
int data = fr.read();
while (data !=-1){
System.out.println ((char)data);
data = fr.read ();
}
// 4、流的关闭操作
fr.close ();
}
//对read()方法的操作升级:使用read的重载方法
public void testFileReader1(){
FileReader fr = null;
// 1、实例化File类对象,指明操作的 文件
try {
File file = new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" );
// 2、提供具体的流,实例化
fr = new FileReader ( file );
// 3、读入的操作
char[] cbuf = new char[5];
int len;
while ((len = fr.read (cbuf)) != -1){
//方式一:
//错误的写法
// for (int i = 0; i <cbuf.length ; i++) {
// System.out.println (cbuf[i]);
// }
//正确的写法
for (int i = 0; i <len ; i++) {
System.out.println (cbuf[i]);
}
//方式二;
String string = new String ( cbuf,0,len );
System.out.println (string);
}
} catch (IOException e) {
e.printStackTrace ();
} finally {
if (fr != null){
try {
fr.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
//从内存中写出数据到硬盘文件里
public void testFileWrite() throws IOException{
// 1、实例化File类对象,指明操作的 文件
File file = new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" );
// 2、提供具体的流,实例化
FileWriter fw = new FileWriter ( file );
// 3、写出的操作
fw.write ( "I have a dream\n" );
fw.write ( "I want you " );
// 4、流的关闭
fw.close ();
}
public static void main(String[] args) {
FileReaderWriterTest fileReaderWriterTest = new FileReaderWriterTest ();
try {
fileReaderWriterTest.testFileReader ();
fileReaderWriterTest.testFileReader1 ();
fileReaderWriterTest.testFileWrite ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
注意:字符流不能处理图片这种等字节数据,应该使用字节流来处理,文本类使用字符类来处理
3、缓冲流的使用
BufferedInputStream;BufferedOutputStream;BufferedReader;BufferedWriter
作用:提供流的读取、写入的速度。
public class BufferedTest {
public void BufferedStreamTest () throws FileNotFoundException{
//1、造文件
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
File srcFile = new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\1.jpg" );
File destFile = new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\11.jpg" );
// 2、造流
// 2.1、造节点流
FileInputStream fis = new FileInputStream ( srcFile );
FileOutputStream fos = new FileOutputStream ( destFile );
// 2.2、造缓冲流
bis = new BufferedInputStream ( fis );
bos = new BufferedOutputStream ( fos );
// 复制的细节:读取,输入
byte[] buffer = new byte[10];
int len;
while ((len = bis.read(buffer)) != -1){
bos.write ( buffer,0,len );
bos.flush ();//刷新缓冲区
}
} catch (IOException e) {
e.printStackTrace ();
} finally {
// 4、资源关闭
// 要求:先关闭外层的流,再关闭内层的流;其中,关闭外层的流时,内层流也会自动关闭。
try {
if (bos!=null){
bos.close ();
}
if (bis!=null){
bis.close ();
}
} catch (IOException e) {
e.printStackTrace ();
}
}
}
//字符流读取文本文件
public void testBufferedWriter(){
BufferedReader br = null;
BufferedWriter bw = null;
//创建文件和相应的流
try {
br= new BufferedReader ( new FileReader ( new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" ) ) );
bw = new BufferedWriter ( new FileWriter ( new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello1.txt") ) );
//方式一:使用char[]数组
char[] cbuf = new char[1024];
int len;
while ((len = br.read (cbuf))!= -1){
bw.write ( cbuf,0,len );
}
//方式二:使用String
String data;
while ((data = br.readLine ()) !=null){
bw.write ( data+"\n" );//data中不包含换行符
}
} catch (IOException e) {
e.printStackTrace ();
} finally {
if (br!=null){
try {
br.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
if (bw!=null){
try {
bw.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
public static void main(String[] args) {
BufferedTest bufferedTest = new BufferedTest ();
try {
bufferedTest.BufferedStreamTest ();
bufferedTest.testBufferedWriter ();
} catch (FileNotFoundException e) {
e.printStackTrace ();
}
}
}
4、对象序列化与反序列化
public class ObjectInputStreamTest {
//序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
public void testObjectInputStream(){
ObjectOutputStream objectOutputStream=null;
try {
objectOutputStream = new ObjectOutputStream ( new FileOutputStream ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" ) );
objectOutputStream.writeObject ( new String ( "传输" ) );
objectOutputStream.flush ();
//自定义类;
objectOutputStream.writeObject ( new Person ( "Tom",12 ) );
objectOutputStream.flush ();
} catch (IOException e) {
e.printStackTrace ();
} finally {
if (objectOutputStream!=null){
try {
objectOutputStream.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
//反序列化
public void testObjectInputStream1(){
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream ( new FileInputStream ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" ) );
Object object = objectInputStream.readObject ();
String string = (String) object;
//读取自定义类的内容
Person person = (Person) objectInputStream.readObject ();
System.out.println (string);
System.out.println (person);
} catch (IOException e) {
e.printStackTrace ();
} catch (ClassNotFoundException e) {
e.printStackTrace ();
} finally {
if (objectInputStream!=null){
try {
objectInputStream.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
public static void main(String[] args) {
ObjectInputStreamTest objectInputStreamTest = new ObjectInputStreamTest ();
objectInputStreamTest.testObjectInputStream ();
objectInputStreamTest.testObjectInputStream1 ();
}
}
其中自定义类的操作如下:
/**
* @Author: 随心的小新
* @Date: 2019/8/21 22:13
* 自定义的对象类,需要满足一些条件才能序列化
* 1、需要实现接口:Serializable
*2、当前类需要提供一个全局常量
* 3、除了当前Person类需要实现Serializable接口之外,还需要保证其内部所有属性也必须是序列化的。
* (默认情况下,基本数据类型是可序列化的)
* 但是当在对象类又添加一个
* 4、不能序列化static与transient修饰的成员变量
*/
public class Person implements Serializable{
public static final long serialVersionUID = 4711111111111L;
private String name;
private int age;
private Account account;
public Person(String name, int age, Account account) {
this.name = name;
this.age = age;
this.account = account;
}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", account=" + account +
'}';
}
}
class Account implements Serializable{
public static final long serialVersionUID = 47111111111L;
private double balance;
public Account() {
}
public Account(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
5、随机读取文件流---RandomAccessFile
/**
* @Author: 随心的小新
* @Date: 2019/8/22 8:39
* RandomAccessFile既可以作为一个输入流,也可以作为一个输出流
* 创建一个RandomAccessFile类实例时需要指定一个mode参数,该参数指定RandomAccessFile的访问模式。
* r:以只读模式打开
* rw:打开后以便读取和写入
* rwd:打开后以便读取和写入,同步文件内容的更新
* rws:打开后以便读取和写入,同步文件内容和元数据的更新
* RandomAccessFile作为输出流时,写入的文件如果不存在,则会自动创建并写入;
* 若文件存在,则会对源文件内容进行覆盖。
*/
public class RandomAccessFileTest {
public void testRandomAccessFile() throws IOException{
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
raf1 = new RandomAccessFile ( new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\1.jpg" ),"r" );
raf2 = new RandomAccessFile ( new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\12.jpg" ),"rw" );
byte[] buffer = new byte[1024];
int len;
while ((len = raf1.read (buffer)) != -1){
raf2.write ( buffer,0,len );
}
} catch (IOException e) {
e.printStackTrace ();
} finally {
if (raf1!=null){
raf1.close ();
}
if (raf2!=null){
raf2.close ();
}
}
}
//对字符文件的写入
public void test2() throws IOException{
RandomAccessFile rafd1 = new RandomAccessFile ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" ,"rw");
rafd1.seek ( 3 );//将指针调到角标为3 的位置
rafd1.write ( "sdfffd".getBytes () );
rafd1.close ();
}
//对文件的插入效果
public void test3() throws IOException{
RandomAccessFile rafd1 = new RandomAccessFile ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" ,"rw");
rafd1.seek ( 3 );//将指针调到角标为3 的位置
//保存指针3后面的所有数据到StringBuilder中
StringBuilder builder = new StringBuilder ( (int) new File ( "G:\\idea练习代码\\yjq_java基础\\src\\main\\java\\com\\example\\demo\\IO流\\流\\hello.txt" ).length () );
byte[] buffer = new byte[20];
int len;
while ((len=rafd1.read ( buffer )) != -1){
builder.append ( new String ( buffer,0,len ) );
}
//调回指针,写入需要插进的数据
rafd1.seek ( 3 );
rafd1.write ( "sdfffd".getBytes () );
rafd1.write ( builder.toString ().getBytes () );
rafd1.close ();
}
public static void main(String[] args) {
RandomAccessFileTest randomAccessFileTest = new RandomAccessFileTest ();
try {
randomAccessFileTest.testRandomAccessFile ();
randomAccessFileTest.test2 ();
randomAccessFileTest.test3 ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
可以使用RandomAccessFile这个类,来实现一个多线程断点下载的功能,下载前都会建立两个临时文件夹,一个是与被下载文件大小相同的空文件,。另一个是记录文件指针的位置文件,每次暂停的时候,都会保存上一次的指针,然后断点下载的时候,会继续从上次的地方下载,从而能够实现断点下载过上传的功能。