第五周笔记

集合框架中的父接口:Collection
子接口: List,Queue,Set
List:有序(索引是按照添加顺序指定的),可重复(存放同一个对象多次,equals方法相同的不同对象)
能存储null元素,没有个数限制。
派生出两个子类:
ArrayList:基于动态数组的数据结构,有连续的索引,从0开始
在使用get/set方法时,效率高
LinkedList:基于双链表的数据结构,每个节点上都有前后两个元素的引用。
在add/remove方法时,效率高
迭代器:用来遍历集合的。提供了hasNext():询问是否有下一个元素
next():用来获取下一个元素。
ps:在迭代期间,想删除集合的元素,需要使用迭代器自己的remove()方法
foreach循环:
for(元素类型 变量:要遍历的集合或数组){
逻辑
}
实现原理:使用了迭代器思想
Queue:队列,进出原则:FIFO
方法: boolean offer(E e)—进
E poll()—–出
E peek()—–查看队首
Deque:队列的子接口,双端队列,两端都可以进可以出
方法:
boolean offerFirst(E e)
boolean offerLast(E e)
E pollFirst()
E pollLast()
E peekFirst()
E peekLast()
栈: 双端队列的特殊情况:一端禁止进出。FILO
方法: void push(E e)–进栈

E pop()—–出栈

泛型机制:
(1)概念
jdk1.5版本开始使用的新特性,本质是进行”参数化类型”,在类
,接口,方法的定义上都可以使用,用来指定数据类型名的。
(2)集合在定义时,可以用泛型机制来指定元素的类型,这样
编译器在编译期间就可以进行检查元素类型是否匹配,避免了
程序在运行时出现过多的错误
(3)集合框架中的所有类型(接口,抽象类,实现类)都是用了
泛型机制
(4)泛型机制的参数只能传引用类型。

    练习:   自定义一个类型,练习泛型机制

           定义一个类型MyContaionner:

使用泛型机制,用于规定要存储的元素类型

List排序
Comparable接口:
如何定义集合中元素之间的大小之分?我们需要在定义元素类型
时实现Comparable接口,实现接口内的compareTo(E e)。实现此接口的类型的对象之间可以进行
比较。

方法:
int compareTo(E e):
比较规则:
(1)this与e比较,this-e,
如果大于0,返回大于0的一个数
如果等于0, 返回0
如果小于0, 返回小于0的一个数
按照升序排序
(2)e-this,降序排序
工具类:Collections
提供了一个sort(Collection c)方法,
对集合里的元素进行排序

 练习:定义一个类型Point,在集合List中存储五个Point对象
         按照到原点的距离长短进行降序排序。     

Comparator比较器接口:
如果元素类型已经实现了comparable接口,定义了默认的比较规则。
之后,再想换其他比较规则时,不修改源码。可以利用比较器接口
来重新定义比较规则

 方法:
 int compare(E o1,E o2);
    比较规则:
    升序: o1-o2

降序: o2-o1

Set接口:
特点1: 无序,存储的元素与添加顺序无关
特点2: 不可重复(使用元素的equals方法来判定是否重复)
特点3: 能存储null元素,只能存储一次。
Hash算法机制
Set集合在添加或查看元素时,当集合中的元素过多时,就是进行
多次的比较,效率变低。
在设计元素类型时,提供hash算法,用于返回对象的一个int值。
在内存中开辟很多小的区域,用于存储一定范围的返回值的对象。
当我们想添加元素或查看元素,先计算此元素的返回值,然后去
相应区域中查找遍历,
–如果在这个区域没有找到对象,说明
集合中可以添加这个对象。
–如果有,然后查看两个对象的equals的返回值
–如果为true, 不能添加
–如果为false, 可以添加,添加至
对应的链表结构中(尽可能的避免发生)
重写HashCode方法:
重写规则:尽可能的让所有的成员变量都参与运算,
尽可能的避免出现hash值碰撞
注意:
重写的必要性:
(1)如果重写了equals(), 有必要重写hashCode方法
(2)如果equals()返回true, hashCode返回值有必要相同
(3)如果equals()返回false,hashCode返回值不一定相同,
如果返回值不同,可以提高检索的效率

反过来说:
(1)hashCode值相同,equals方法可能不同
(2)hashCode值不同,equals方法一定不同

Set接口派生的子类
HashSet:通过实现hash算法的一种数据结构,
无序,不重复
LinkedHashSet:通过实现hash算法的一种数据结构,但是
通过链表来维持顺序。顺序与添加顺序一致。
TreeSet: 使用二叉树的一种数据结构,顺序与自然排序有关系。
支持定制排序
Set集合:
特点:无序,不重复。
存储时采用了hash算法机制,计算存储位置。

HashCode方法:
Object是引用类型的父类,提供了hashCode()方法以及equals()方法
因此我们在定义类型时,一般都重写hashCode和equals方法。
重写的重要性:
equals方法我们用来判断集合中的元素是否重复
hashCode方法我们在使用Set集合时,必须要重写,因为
我们采用的hash算法计算Set集合元素的存储位置。

int hashCode():
    Object提供的方法是通过地址计算hash值,不可控。
            我们需要在自定义类中重写此方法。
            重写原则:    尽可能的让所有成员变量都参与运算
                                    尽可能的减少hash值的碰撞

public int hashCode(){
    int result = 7;--定义一个局部变量,进行初始化
    int prime = 53 --定义一个局部变量,赋值为素数
    result = prime*result+field1;
    result = prime*result+field2;
    return result;

}

Set集合的遍历
因为Set集合是无序的,无下标可言,因此不能使用经典for
循环。我们可以使用迭代器原理。

(1) 调用集合的iterator()获取迭代器
(2) 使用foreach循环

Set集合的元素:
不能轻易修改参与hash值算法的成员变量。
否则容易引起内存溢出。
原因:成员变量修改后,会出现新的hash值,但是存储位置还在
原hash值的位置上。因此操作时,找不
到具体的存储位置。

子类:
HashSet:
无序,不重复,底层使用hash算法计算存储位置。
增加删除时效率高
LinkedHashSet:是HashSet的子类
底层使用hash算法计算存储位置,同时使用链表来维护
顺序,顺序与添加顺序一致。
在查看检索时,效率比较高
TreeSet:是SortedSet子接口的实现类,使用二叉树的数据结构维护

元素的顺序。

Map接口:集合框架中的另一个父接口
Map集合,用于储存一一对应的元素数据,第一个对象可以作为
索引,第二个对象作为值,我们称之为key-value,键值对。

储存数据的特点:
 (1)以key-value形式进行存储。
 (2)key与value都必须是引用类型
 (3)key可以为null。
 (4)key与value是单向一对一映射。
 (5)key不能重复

存储机制:
Map是基于数组和链表的数据结构进行存储数据。
作为key的对象采用了hash算法计算存储的数组
(散列数组,散列桶)的位置.如果计算出来的位置,
数组中此位置没有元素,就可以添加到
散列桶内,如果有元素,key的equals方法
返回值为false,就会存储在散列桶元素对应的单向链表中。
如果key的equals方法返回true,就进行替换(覆盖)。
PS:使用Map集合,做为key的数据类型应该重写equals和
HashCode方法
常用方法:
V put(K k,V v):
作用:用于存储一对key-value. 返回被替换的value值
如果不是替换就返回null
V get(K k):
作用:通过key对象,获取对应的value对象,如果集合中
没有此key,返回null
Map集合的遍历
Set keySet();
用于获取Map中所有的key对象,返回一个Set集合
Set

}

Map接口的子类:

HashMap与HashTable的区别
(1)HashTable是一个古老的类。不建议使用
(2)HashTable是一个线程安全的类,HashMap线程不安全
(3)HashTable的key不能是null,HashMap可以是null
LinkedHashMap:是HashMap子类,使用链表来维护key-value的
顺序,在迭代时顺序与添加顺序一致。
TreeMap:
是SortedMap子接口的实现类,使用了二叉树的数据结构维护
填入集合的顺序。
(1)自然排序:
往TreeMap里添加的key对象,可以实现Comparable接口。重写
compareTo方法
(2)定制排序:做为key对象的数据类型,可以不实现Comparabel接口。
需要创建一个比较器Comparator对象。实现compare方法
Properties:
是HashTable的子类型,用于封装属性文件的key-value信息
因为在文件里写的都是字符串,因此Properties的key与value

都是字符串类型

File类型
java.io.File类型,可以对硬盘上的文件以及目录,进行操作。
如查看文件/目录的属性信息,创建,删除文件/目录。此类型
不能查看和修改文件里的内容。
常用构造器:
File(String pathname):
指定一个路径,创建一个File对象

        路径:
        (1)文件的路径,要写到文件的扩展名为止
        (2)目录的路径,要写到当前目录的名称为止          

常用方法:
boolean exists():
判断指定路径的File对象是否存在
exists();//
isFile();
isDirectory();
getName());
lastModified();
isAbsolute();
getAbsolutePath();
getParent();
length();
java.io.File类型
一、概念
可以用来创建,删除文件/目录,还可以查看文件/目录的属性信息。
但是不可以修改文件里的数据。如果需要修改,应该使用输入/输出流。
二、常用构造器
File(String pathname)
创建一个指定路径的File对象
File(File parent,String child)
在指定parent路径下,创建一个child的file对象
File(String parent,String child)
在指定parent路径下,创建一个child的file对象

三、
绝对路径:是从根目录开始写的路径
window: 从盘符开始书写:
D:\a\f1.txt
D:\a\b
linux: /home/scott/f1.txt
/home/scott
相对路径: 相对某一文件/目录的路径,不是从根路径书写。
reg: f2.txt相对于a目录的路径:
window: b\f2.txt
linux: b/f2.txt
reg: f3.txt相对于f2.txt的路径
../c/f3.txt

四、常用方法
boolean exists();判断指定的路径是否存在
boolean isFile();判断指定路径是不是文件
boolean isDirectory();判断指定路径是不是目录
String getName());获取文件/目录名称
long lastModified();获取文件/目录的最后修改时间
boolean isAbsolute();判断指定路径是不是绝对路径
String getAbsolutePath();获取绝对路径
String getParent();获取父目录的路径
long length();获取文件大小

文件/目录创建方法:
boolean createNewFile();创建文件
boolean mkdir();创建目录
boolean mkdirs();创建多级目录
文件/目录的删除方法
boolean delete()
       可以删除文件,删除目录时,需要目录下没有文件或子目录
File[] listFiles()
    获取目录里的file对象

递归:
递归思想:分成递与归。一层层递进,最后再一层层归。
两种递归:
(1) 方法调用自己
(2) 方法A调用方法B,方法B调用A
举例:
n*(n-1)*……*1

 z = f(n) 计算n的阶乘
   = n*f(n-1)
   = n*(n-1)*f(n-2)
   = n*(n-1)*......*1

   f(n)是一个函数:
           里的逻辑:
            n*f(n-1)

练习:
斐波那契数列: 第n个数是第n-1个数与第n-2个数的和。

1,1,2,3,5,8,13,.......

计算第10个数的值。

IO流:(Input,Output)
我们在做项目时,除了自定义的一些数据外,还可能需要从”外界”
引入数据,或者将数据导出到”外界”。这时,我们需要I/O操作。
外界:指的可能是 键盘,显示器,硬盘,另外一个程序。
输入:又叫读入操作
数据时从”外界”流向程序
输出:又叫写出操作
数据时从程序流向”外界”

流: 就是数据序列, 一经创建成功,就会打开一个通道。所以使用完
应该进行关闭操作。
IO流的分类:
(1)按照流向分类:
输入流
输出流
(2)按照处理的数据单位分类:
字节流
字符流
(3)按照功能分类:
节点流:直接连接两个设备的流类型

处理流:对节点流再次封装与处理的流类型

字节流:
抽象父类 InputStream/OutputStream
文件字节流:
FileInputStream/FileOutputStream

(1)构造器:
FileInputStream(File file)
创建一个指定路径的File对象的文件输入流对象
FileInputStream(String name)
创建一个指定路径的字符串的文件输入流对象
常用方法:
int read()
读取该流中的一个字节数据,即8位二进制,存储到一个int数
据的低八位上
如果返回-1,读至文件末尾,
long skip(long n)
跳过流中n个字节
int read(byte[] b)
读取字节存入byte数组中,最多能读b.length个字节
返回的是实际读取的字节个数
int available()
查看此输入流中剩余的字节数量

(2)构造器
   FileOutputStream(File file) 
   FileOutputStream(File file, boolean append) 
   FileOutputStream(String name)
   FileOutputStream(String name, boolean append)
         创建一个指定路径的输出流对象,append表示在文件末尾追加

   PS:如果指定路径下的文件名不存在,会自动创建。
                如果父路径不存在,则报异常FileNotFoundException
         常用方法:
   void write(int b)
               写出参数b中的一个字节,int类型的低八位。
   void write(byte[] b)
               将字节数组b中的字节按顺序写出
   void write(byte[] b,int off,int len)
              将字节数组b中的字节按顺序写出,从下标off,写len个 
              File:可以创建,删除,查看文件/目录的信息。但是不
        能查看/修改文件里的内容

删除目录时:需要注意使用递归思想(不能直接删除不为空的目录)
IO流:
用途,传输数据。
输入:读取数据
输出: 写出数据
流:数据序列
分类:
(1)按照流向分类
(2)按照处理的单位分类
(3)按照功能分类
字节流:
抽象父类:
InputStream:定义了字节输入流的常用方法
int available()
void close();
int read():读取一个字节,存入int的低八位上,范围是0-255
int read(byte[] b):
读取字节存入字节数组b中,返回的是读取的有效字节个数。
int read(byte[] b,int off,int len)
skip(int n);
OutputStream:定义了字节输出流的常用方法
void close();
void flush();//冲刷,作用是将流的数据,冲刷进文件中
void write(int b);写一个字节
void write(byte[] b);写一个字节数组
void write(byte[] b,int off,int len)
子类:
FileInputStream/FileOutputStream
继承了字节流的抽象父类。重写了方法,并且提供了自己独有的方法
构造器:
FileInputStream(File file)
FileInputStream(String path)

   FileOutputStream(File file)
   FileOutputStream(File file,boolean append)
   FileOutputStream(String pathname)
   FileOutputStream(String pathname,boolean append)

   PS:所有的输出流,对于指定的路径中的文件若是不存在,

都会自动创建。

缓冲流:
BufferedOutputStream:字节缓冲输出流
在写数据时,如果一个字节一个字节的写,写的次数明显很多,效率就会变得很低。
如何提高效率呢。
缓冲输出流的特点是:在流里维护了一个缓冲区,写字节时,先将字节
写入缓冲区, 当缓冲区满时,再一次性的将数据写到文件里。这样就
降低了写的次数,因此提高了效率。

    因此缓冲输出流缺失即时性,可以使用flush方法进行冲刷

    常用构造器:
    BufferedOutputStream(OutputStream out)
            创建一个指定字节输出流的缓冲流对象
    BufferedOutputStream(OutputStream out,int size)
            创建一个指定字节输出流的缓冲流对象,并设置缓冲区的大小
    PS:当一次写的字节超出缓冲区大小,会不使用缓冲区直接写在硬盘中  

     常用方法:
    void write(int b):
                    写int数据的低八位,写入缓冲区内
    void write(byte[] b,int off,int len)
                    写指定长度len的字节数组,写入缓冲区  




BufferedInputStream:字节缓冲输入流
   在读取字节时,也是一个字节一个字节的读,次数多,效率低。
   使用缓冲输入流,内部维护了一个缓冲区,默认8k,先一次性将缓冲区装满
   等待读取.
   当将缓冲区的数据读完,缓冲区再次存储后续数据。读取的次数明显降低
    效率高      

   构造器:
   BufferedInputStream(InputStream is);
   BufferedInputStream(InputStream is,int size);
常用方法:
   int read(byte[] bs)
          读取缓冲区里的字节存储bs中,
          当一次性得去的字节小于缓冲区,我们是从缓冲区里读数据。
          此时,效率高  

          当一次性读取的字节超出缓冲区大小。
          不使用缓冲区,直接从文件里读。

int read(byte[] bs,int off,int len)

数据字节流,与缓冲流一样,父类都是过滤字节流(
FilterOutputStream/FilterInputStream
)
这两个类提供了几个特殊的方法,可以直接写基本数据类型

数据输出流:DataOutputStream
构造器:
DataOutputStream(OutputStream os)
创建一个指定字节输出流的数据输出流对象

 常用方法:
        除了提供写一个字节和写一个字节数组的方法外,还提供了如下方法      
  writeByte(int b)
  writeShort(int s) 
  writeInt(int i)
  writeLong(long l)
  writeFloat(float f)
  writeDouble(double d);
  writeChar(int c);
  writeBoolean(boolean b)
  writeUTF(String s);
  对象流:
有的时候,我们可能需要将内存中的对象持久化到硬盘上,或者将
硬盘中的对象信息读到内存中,这个时候我们需要使用对象输入
输出流。

 序列化: 是对象转换成一个字节序列的过程,是一个写操作

反序列化: 一个字节序列转换成对象的过程 ,是一个读操作

ObjectOutputStream
构造器:

 ObjectOutputStream(OutputStream out) 
      创建一个指定字节输出流的对象输出流对象。

      常用方法: 除了提供了一些基本数据类型的写方法外,还提供了
 void writeObject(Object obj)
            将内存中的对象持久化到硬盘上 

ObjectIntputStream
ObjectIntputStream(OutputStream out)
创建一个指定字节输入流的对象输入流对象。

      常用方法: 除了提供了一些基本数据类型的读方法外,还提供了
 Object readObject();
           从硬盘上读取一个字节序列,转换成对象

Serializable:序列化接口
如果想将对象序列化,那么对象的类型必须实现此接口。此接口
内什么都没有,只是一个序列化标识。

serialVersionUID:
每个能序列化的对象,在被序列化时,系统会默认给此对象的类计算一个
序列化版本号。不同的平台默认提供的序列化版本号多数情况下不会相同。
因此当我们反序列时,如果硬盘里存储的对象的版本号与当前设计的类型
的版本号不一致。会出现运行时异常:
java.io.InvalidClassException,这种情况叫不兼容问题。

  如果我们想解决不兼容问题。我们应该手动提供版本号。尽可能的相同
  这样来解决不兼容问题

  另外一种情况:
      序列化过后,可能会修改类型,如果使用系统默认提供的
      版本号,在反序列时,会有异常,如果手动提供,不出现异常
     多出来的成员变量,以默认值的形式,赋值给反序列化回来的对象。

transient:成员变量的一个修饰词,可以理解为瘦身。
有的时候,在序列化对象时,我们不需要将对象的某些成员变量
值持久化到硬盘上(因为不重要),此时,我们可以在这些成员变量

前添加修饰词transient(保存时,进行减肥)

字符流:
在输出输入操作时,以字符为单位进行操作,默认是unicode编码集
字符流的抽象父类分别是
Writer/Reader
Writer提供了字符输出流的常用方法
void close():关闭
void write(char[] cbuf):写一个字符数组
void write(char[] cbuf, int off, int len)
写一个字符数组的一部分
write(int c):写一个字符
write(String str):写一串字符
write(String str, int off, int len)
写字符串的一部分
Reader提供了字符输入流的常用方法
int read():读一个字符,存储到int的低16位
int read(char[] cbuf):将数据读进字符数组中,返回的是读取的有效字符个数
int read(char[] cbuf, int off, int len)

将字符读入数组的一部分。

子类中转换流:
OutputStreamWriter:
将字符转换成字节写出到硬盘上
构造器:
OutputStreamWriter(OutputStream out)
创建一个指定字节输出流的字符输出流对象,采用的是系统默认的编码集
OutputStreamWriter(OutputStream out, Charset cs)
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
OutputStreamWriter(OutputStream out, String charsetName)
创建一个指定字节输出流的字符输出流对象,采用指定编码集。

 write(int a);
        当a的低16位,如果被设计成相应的字符时,如果两个字节都是
        有效字节,会写出两个。如果低16位对应是无效字符,或是有效
        字节只有一位时,会写一个字节。      





InputStreamReader()
         将字节转换成字符读进程序中
构造器:
InputStreamReader(InputStream in) 
    创建一个使用默认字符集的InputStreamReader。  
InputStreamReader(InputStream in, Charset cs) 
InputStreamReader(InputStream in, CharsetDecoder dec) 
InputStreamReader(InputStream in, String charsetName) 

创建一个使用指定字符集的InputStreamReader。

缓冲流:

PrintWriter:提供了丰富的方法,比BufferedWriter更加常用,此类型提供了
行自动刷新的功能
构造器:
PrintWriter(File file)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out, boolean autoFlush)
PrintWriter(String fileName)
PrintWriter(Writer out)
PrintWriter(Writer out, boolean autoFlush)

   上述构造器,有第二个参数的,可以设置为true,表示行自动刷新。  
   只有一个参数的构造器,相当有两个参数时,设置为false的情况,即取消了
   行自动刷新的功能

 常用方法:
    println() 
            通过写入行分隔符字符串来终止当前行。 
    println(boolean x) 
    打印一个布尔值,然后终止该行。  
    void println(char x) 
    打印一个字符,然后终止该行。  
    void println(char[] x) 
    打印字符数组,然后终止行。  
    void println(double x) 
    打印双精度浮点数,然后终止行。  
    void println(float x) 
    打印一个浮点数,然后终止该行。  
    void println(int x) 
    打印一个整数,然后终止该行。  
    void println(long x) 
    打印一个长整型,然后终止行。  
    void println(Object x) 
    打印一个对象,然后终止该行。  
    void println(String x)  

BufferedReader:提供了一个缓冲区

    构造器:   
  BufferedReader(Reader in) 
        创建使用默认大小的输入缓冲区的缓冲字符输入流。  
  BufferedReader(Reader in, int sz) 
        创建使用指定大小的输入缓冲区的缓冲字符输入流。
    常用方法:  
  String readLine():
            读一行字符串,读至换行符号为止,返回的数据不包含换行符

当返回值为null时,表示读至文件末尾

文件字符流:
FileWriter/FileReader

FileWriter:相当于OutputStreamWriter与
FileOutputStream合起来的功能,内部也维护
了一个缓冲区,但是需要手动flush
构造器:
FileWriter(File file)
FileWriter(File file, boolean append)
FileWriter(String fileName)
FileWriter(String fileName, boolean append)

    append:表示追加,但是此流不能设置字符集。
    常用方法与 OutputStreamWriter的差不多

FileReader:相当于InputStreamReader和FileInputStream合起来的功能
内部也维护了一个缓冲区
构造器:
FileReader(File file)
FileReader(String fileName)

常用方法与InputStreamReader的方法差不多

System是一个final修饰的类型
两个成员变量
out:是PrintStream类型,默认的输出目的地是控制台console
in: 是InputStream类型, 默认的数据源是键盘

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值