1. Java API String类
1.1. 什么是API
Ÿ API全名:Application Programming Interface,API是应用程序编程接口,指一些预先定义好的类。
Ÿ 例如我们想要一台电脑,并不需要自己生产每个零件,只要从各个厂商买到组装电脑的零件就可以,然后根据说明书学会使用,将零件安装在一起就得到了电脑。电脑就像是我们要的程序,而零件就是API,说明书就是帮助文档。
1.2. Java API
Ÿ Java API就是Sun公司提供给我们使用的类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用。
Ÿ 我们可以通过查帮助文档来了解Java提供的API如何使用
1.3. Java中常用API
Ÿ String类
对字符串进行操作通常我们使用String类,相关的还有StringBuffer和StringBuilder
Ÿ 集合类
集合是一种容器,用来存取对象(Collection、Map)
Ÿ 包装类
Java定义了一组包装类对基本数据类型进行了包装(Integer、Double、Boolean)
Ÿ 时间对象
Java定义了一些类方便用户对时间、日期进行处理(Date、Calendar)
Ÿ 系统类
Java定义了一些类针对系统进行操作(System、Runtime)
Ÿ IO流
Java定义了一些类对数据传输进行了封装(输入输出流、File文件对象)
Ÿ Socket
Java定义了一些类方便用户进行网络编程(Socket、DatagramSocket)
1.4. String对象的存储
Ÿ 字符串是常量,一旦创建不能被修改。
Ÿ 字符串在程序中经常使用,虚拟机会将其缓存在String池中。
Ÿ 了解 String s = “abc” 和 String s = new String(“abc”) 的区别。
1.5. String类的构造函数
Ÿ String(byte[] bytes)
通过指定字节数组构建字符串。
Ÿ String(byte[] bytes, int offset, int length)
通过指定字节数组、数组元素偏移量和元素个数构建字符串。
Ÿ String(byte[] bytes, String charsetName)
通过指定字节数组和指定码表构建字符串。
Ÿ String(byte[] bytes, int offset, int length, String charsetName)
通过指定字节数组、数组元素偏移量、元素个数和指定码表构建字符串。
Ÿ String(char[] value)
通过指定字符数组构建字符串。
Ÿ String(char[] value, int offset, int count)
通过指定字符数组、数组元素偏移量和元素个数构建字符串。
Ÿ String(StringBuffer buffer)
通过指定StringBuffer构建字符串。
Ÿ String(StringBuilder builder)
通过指定StringBuffer构建字符串。
1.6. String类的常用方法
Ÿ char charAt(int index)
查找指定位置的字符
Ÿ int indexOf(String str)
判断字符串出现的位置
Ÿ int compareTo(String anotherString)
按字典顺序比较两个字符串
Ÿ String substring(int beginIndex, int endIndex)
截取子字符串
Ÿ String[] split(String regex)
字符分割
Ÿ String replace(CharSequence target, CharSequence replacement)
替换字符串
Ø 字符串练习
Ÿ 设计一个方法, 获取一个已知文件名的扩展名.
Person.java的扩展名是.java,Person.java.txt的扩展名是.txt
Ÿ 设计一个方法, 查找一个字符串中子字符串出现的所有位置.
“xxxabcxxxabcxxx”中abc出现了2次,索引位置是3和9
Ÿ 查找一个字符串中出现最多的字符.
“hello world”中L出现了3次
Ÿ 设计方法,使用System.in.read()读取一行.
循环读取一个字节,读取到\r\n结束。考虑中文问题
Ÿ 已知一个字符串. 设计一个方法, 可以从这个字符串中打印n个字节. 但不能打印出半个中文.
短信一次发送字节140个,如果超过140字节就会分为两条。这时如果第140个字节是中文的前半,那么第一条短信应该发送139字节。
Ÿ 查找两个字符串中最大相同子串.
“abc”和“bcd”的最大相同子串是”bc”
“xyzabcdefxyz”和“xxxabcdefooo”的最大相同子串是”abcdef”
2. 集合类
2.1. 集合概念
Ø 为什么出现集合类?
Ÿ 在面向对象的编程思想中,都是以对象的形式对事物进行描述的,为了保证对象的生命周期,我们需要持有对象
Ÿ 在很多情况下,我们不知道在程序中需要创建多少个对象,这时就不能依靠定义引用对象的变量来持有每一个对象
Ÿ 存储对象的容器就能帮我们解决这样的问题,而集合便是这样的容器
Ø 数组和集合类的区别
Ÿ 数组和集合类都是容器,都能存储对象
Ÿ 集合类的优势就在于长度可变
Ø 集合类的特点
Ÿ 集合类可用于存储对象
Ÿ 集合类的长度可变
Ÿ 一个集合可以存储多种类型的对象
2.2. 集合接口
Ø Collection接口
Ÿ 一个独立的元素的序列,这些元素服从一条或多条规则
Ÿ Collection接口下主要分为List集合和Set集合
Ÿ List集合的特点是元素有序、允许有重复元素
Ÿ Set集合的特点是元素无存储顺序、不允许有重复元素
Ø Map接口
Ÿ 一组成对的”键值对”对象,允许根据键来查找值
Ÿ Map集合的键不允许有重复,所以Map的所有键构成了一个Set集合
Ÿ 主要学习HashMap和TreeMap
Ø Iterable接口
Ÿ JDK1.5新定义的接口作为Collection的父接口
Ÿ 主要为了实现增强for循环
2.3. List
Ø List特点
Ÿ 元素有序,可重复。
Ÿ 我们主要学习三种:ArrayList、Vector、LinkedList
Ÿ 这三种都是List接口的实现类,使用上完全一样,只是实现原理不同,效率不同。
Ø ArrayList
Ÿ 底层数组实现
Ÿ 查找快,增删慢
Ÿ 线程不安全
Ø Vector
Ÿ 与ArrayList基本一样
Ÿ 线程安全(线程同步),效率低
Ø LinkedList
Ÿ 底层链表实现
Ÿ 增删块,查找慢
Ø 存取元素
Ÿ List集合元素存取方法一致
Ÿ 使用add()方法增加元素
Ÿ 由于List集合有序,可以使用get()方法获取元素
Ÿ 元素的迭代(Iterator)
通过集合对象的iterator()方法获得迭代器Iterator
通过Iterator迭代器的hasNext()方法判断是否存在下一个元素
通过Iterator迭代器的next()方法获取下一个元素
Ÿ 元素的迭代(Enumeration)
迭代Vector集合中的元素可以使用Enumeration
通过Enumeration的hasMoreElements()方法判断是否还有元素
通过Enumeration的nextElement()方法返回下一个元素
2.4. JDK5新特性
Ø 泛型
Ÿ 由于集合可以存储不同类型的数据,所以取元素时有可能会导致类型转换错误
Ÿ JDK1.5增加了新特性泛型,为了减少操作集合时出错的几率
Ÿ 集合一旦声明了泛型,便只能存储同一类型的对象了
Ÿ 使用方法:ArrayList<Person> al = new ArrayList<Person>();
Ÿ 使用泛型的好处
提高了程序的安全性
将运行期遇到的问题转移到了编译期
省去了类型强转的麻烦
泛型类的出现优化了程序设计
Ø 增强for循环
Ÿ 新接口Iterable中定义了增强for循环
Ÿ 可以通过增强for循环对数组和集合进行遍历
Ÿ 语法:for(类型 变量名 : 要遍历的容器) { …… }
Ø 可变参数
Ÿ 有的时候在设计方法时无法确定将来别人会传入的参数个数
Ÿ JDK1.5增加了新特性可变参数,在函数中只声明参数类型,不规定个数
Ÿ 方法接受的参数实际上是一个数组,可以在方法中遍历数组
Ÿ 可变参数只能被定义为函数的最后一个形参
Ÿ 语法格式: 返回值 函数名(参数类型… 形参名)
2.5. Set
Ø Set集合无序,不允许有重复元素
Ÿ Set集合通过存入对象的equals方法来保证集合中没有重复元素
Ø HashSet
Ÿ HashSet是Set的子类,因此也没有重复元素
Ÿ 底层使用哈希算法保证没有重复元素
Ÿ 存储对象时,先调用对象的hashCode()方法计算一个哈希值,在集合中查找是否有哈希值相同的对象。
如果没有哈希值相同的对象,直接存入。
如果有哈希值相同的对象,则和哈希值相同的对象进行equals()方法比较。
equals()方法比较结果相同则不存,不同就存入。
Ÿ 往HashSet集合里存储的对象必须正确重写hashCode和equals方法
Ø TreeSet
Ÿ TreeSet集合通过二叉树算法保证无重复元素,并对元素进行排序
Ÿ 在使用TreeSet时必须指定比较的算法,指定的方式有两种:
自然顺序:将要存储的类实现Comparable接口,重写compareTo方法,在方法中指定算法
比较器顺序:在创建TreeSet时,传入一个比较器Comparator,在比较器的compare方法中指定算法
2.6. Map
Ø Map集合的特点
Ÿ Map存储了一系列键值的映射关系
Ÿ Map集合需要保证键的唯一性
Ÿ 可以通过键获得值,反之则不能
Ÿ Map集合存储元素使用put(key,value)方法
Ø Map集合的两种遍历方式
Ÿ 通过keySet方法返回由键组成的集合,迭代该集合的元素就拿到了所有的键,再调用get方法根据键拿到值
Ÿ 通过entrySet方法返回键值映射关系组成的集合,迭代该集合就拿到了一个个的键值映射关系,通过getKey方法拿到键,通过getValue方法拿到值。
Ø HashMap
Ÿ 线程不安全,存取速度快,允许存放null键,null值。
Ÿ 通过HashSet原理保证键唯一性
Ø Hashtable
Ÿ 线程安全,速度慢,不允许存放null键,null值,已被HashMap替代。
Ø TreeMap
Ÿ 通过二叉树算法保证键唯一性
Ÿ 对键进行排序,排序原理与TreeSet相同。
Ø Properties
Ÿ HashTable的子类,所以也是线程安全的
Ÿ 用于读写配置文件的,一般配置项等号两边都是String,所以该集合中的两列保存的都是String类型的数据
Ÿ 这个集合中只能存String,所以不需要定义泛型。
3. 其他常用类
3.1. 工具类
Ø Arrays
Ÿ 工具类,提供了对数组的常用操作
Ÿ 将数组转成List集合
Ÿ 对数组进行排序
Ÿ 对数组进行二分查找
Ÿ 将数组转为字符串显示形式
Ø Collections
Ÿ 工具类,提供了对集合的常用操作
Ÿ 对集合进行查找
Ÿ 取出集合中的最大值,最小值
Ÿ 对List集合进行排序
3.2. 包装类
Ø JDK提供了对所有数据类型的包装类
Ÿ byte >>> Byte
Ÿ short >>> Short
Ÿ int >>> Integer
Ÿ long >>> Long
Ÿ double >>> Double
Ÿ float >>> Float
Ÿ char >>> Character
Ÿ boolean >>> Boolean
Ø 包装类的常用方法
Ÿ toString方法
Ÿ parseInt方法:Integer.parseInt(String s)
Ÿ valueOf方法:Double.valueOf(String s)
3.3. 系统类
Ø System类
Ÿ 静态属性in为标准输入流,属于InputStream类型,read方法返回一个字节
Ÿ 静态属性out为标准打印流,属于PrintStream类型,print方法打印字符
Ÿ 可以用set方法修改属性in和out
Ÿ System.exit()方法退出Java虚拟机
Ÿ System.gc()垃圾回收
Ÿ System.getProperties()方法获得系统属性
Ø Runtime类
Ÿ 表示系统运行时状态
Ÿ exec方法执行命令
3.4. 时间类
Ø Date类
Ÿ 使用new Date()创建时间对象代表当前系统时间
Ÿ 需要使用DateFormat类来进行格式化,才能显示想符合习惯的格式
Ø Calendar类
Ÿ 使用该类对时间进行操作比较方便
Ÿ 通过常量来表示时间的各种值,如一年中的某一天,一个月的某一天等
Ÿ 将对应的常量作为形参来调用相应的get、add、set方法来操作对象
Ø 练习
Ÿ 计算出某一年的二月份有多少天?
Ÿ 设计一个方法可以计算工作时间,接收一个参数(工作日),方法打印出哪天完工。
4. IO(Input Output)
4.1. IO流概念
Ÿ IO流用来处理设备之间的数据传输
Ÿ Java对数据的操作是通过流的方式
Ÿ Java用于操作流的对象都在IO包中
Ÿ 流按操作对象分为两种:字节流与字符流。 字节流可以操作任何数据,字符流只能操作纯字符数据比较方便。
Ÿ 流按流向分为:输入流,输出流。
4.2. IO流常用基类
Ø 字节流的抽象基类:
Ÿ InputStream ,OutputStream
Ø 字符流的抽象基类:
Ÿ Reader , Writer
Ø 由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
Ÿ 如:InputStream的子类FileInputStream。
Ÿ 如:Reader的子类FileReader。
Ÿ InputStreamReader是Reader的子类
4.3. IO程序书写
Ÿ 使用前,导入IO包中的类
Ÿ 使用时,进行IO异常处理
Ÿ 使用后,释放资源
4.4. 字符流读写文件
Ø 读取文件
Ÿ 定义字符流关联指定文件
FileReader reader = new FileReader("Test.txt");
Ÿ 读取一个字符,返回int,该字符的码表值
int ch = reader.read();
Ÿ 关闭流,释放资源
reader.close();
Ø 写出文件
Ÿ 定义字符输出流关联指定文件
FileWriter writer = new FileWriter("Test.txt");
Ÿ 写出一个字符,接收int码表值
writer.write(97);
Ÿ 关闭流,释放资源
writer.close();
Ø 注意事项
Ÿ 文件路径
定义文件路径时Windows中的目录符号为“\”,但这个符号在Java中是特殊字符,需要转义。
可以用“\\”或“/”表示。
Ÿ 读取文件
读取文件时必须保证文件存在,否则将抛出FileNotFoundException。
Ÿ 写出文件
写出时文件如不存在时程序会创建新文件,如文件已存在则会清空原文件内容重新写入。
如需追加内容可调用FileWriter构造函数FileWriter(String fileName, boolean append)
Ÿ 练习
拷贝一个文件
4.5. 字符流缓冲区读写
Ø 自定义缓冲区读写
Ÿ 为什么定义缓冲区
由于单个字符读写需要频繁操作文件,所以效率非常低。
我们可以定义缓冲区将要读取或写出的数据缓存,减少操作文件次数。
Ÿ 缓冲区读取
先定义一个数组,然后调用FileReader读取一个数组的方法。
int read(char[] cbuf)
Ÿ 缓冲区写出
将要写出的数据存放在数组中,调用FileWriter方法,一次写出一个数组。
void write(char[] cbuf, int off, int len)
Ø 内置缓冲区的BufferedReader和BufferedWriter
Ÿ Java提供了带缓冲功能的Reader和Writer类:BufferedReader,BufferedWriter
Ÿ 这两个类都是提供包装功能,需要提供其他流来使用,给其他流增加缓冲功能
Ÿ 当我们调用BufferedReader读取数据时,程序会从文件中一次读取8192个字符用来缓冲
Ÿ 当我们调用BufferedWriter写出数据时,程序会先将数据写出到缓冲数组,直到写满8192个才一次性刷出到文件
4.6. 装饰设计模式(Decorator)
Ø 什么情况下使用装饰设计模式
当我们需要对一个类的功能进行改进、增强的时候
Ø 装饰模式的基本格式。
含有被装饰类的引用
通过构造函数传入被装饰类对象
和被装饰类含有同样的方法,其中调用被装饰类的方法,对其进行改进、增强
和被装饰类继承同一个类或实现同一个接口,可以当做被装饰类来使用
Ø 了解BufferedReader、BufferedWriter的原理。
BufferedReader、BufferedWriter都是装饰类,他们可以装饰一个Reader或Writer,给被装饰的Reader和Writer提供缓冲的功能。
就像我们用BufferedReader、BufferedWriter装饰FileReader和FileWriter,使用的读写功能还是FileReader和FileWriter的,但给这两个类的读写添加了缓冲功能。
Ø 练习
Ÿ 模拟一个BufferedReader类。
Ÿ 模拟一个LineNumberReader类。
4.7. 字节流
Ÿ 基本操作与字符流相同
Ÿ 字节流可以操作任意类型数据
Ÿ 练习:拷贝一个Jpg文件
4.8. 字节流缓冲区读写
Ø 自定义缓冲区读写
Ÿ 原理和字符流相同,都是为了提高效率
Ÿ 定义数组缓冲数据,一次读取一个数组,一次写出一个数组,减少操作文件的次数
Ø BufferedInputStream、BufferedOutputStream
Ÿ 和BufferedReader、BufferedWriter原理相同,都是包装类
Ÿ BufferedInputStream、BufferedOutputStream包装InputStream和OutputStream提供缓冲功能
4.9. 转换流
Ÿ 字符流与字节流之间的桥梁
Ÿ 方便了字符流与字节流之间的操作
Ÿ 字节流中的数据都是字符时,转成字符流操作更高效
Ÿ 练习:转换System.in
4.10. 标准输入输出流
Ÿ System类中的成员变量:in,out。
Ÿ 它们各代表了系统标准的输入和输出设备。
Ÿ 默认输入设备是键盘,输出设备是显示器。
Ÿ System.in的类型是InputStream.
Ÿ System.out的类型是PrintStream是OutputStream的子类FilterOutputStream 的子类.
Ÿ 练习:通过修改标准输入输出流,使用System.in和System.out拷贝文件
4.11. 流基本应用小节
Ÿ 流是用来处理数据的。
Ÿ 处理数据时,一定要先明确数据源,或者数据目的地
Ÿ 数据源可以是文件,可以是键盘或者其他设备。
Ÿ 数据目的地可以是文件、显示器或者其他设备。
Ÿ 而流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。
字符流 |
Reader |
Writer |
InputStreamReader |
OutputStreamWriter |
FileReader |
FileWriter |
BufferedReader |
BufferedWriter |
FileInputStream |
字节流 |
FilterInputStream |
FilterOutputStream |
BufferedInputStream |
BufferedOutputStream |
InputStream |
OutputStream |
FileOutputStream |
4.12. File类
Ÿ 用来将文件或者文件夹路径封装成对象
Ÿ 方便对文件与文件夹进行操作。
Ÿ File对象可以作为参数传递给流的构造函数。
Ÿ 了解File类中的常用方法。
4.13. 递归
Ÿ 函数自己调用自己。
Ÿ 注意:递归时一定要明确结束条件。
Ÿ 应用场景:
当某一功能要重复使用时。
Ÿ 练习:
列出一个文件夹下所有的子文件夹以及子文件
Ÿ 思考:
删除一个目录的过程是如何进行的?
复制一个目录的过程呢?
4.14. IO包中的其他类
Ÿ 序列流
SequenceInputStream
可以将多个字节输入流整合成一个流,在使用这个流读取的时候,读到第一个流的末尾时继续读第二个,第二个读到末尾则继续读第三个,以此类推,直到读到最后一个流的末尾返回-1
Ÿ 打印流
PrintStream 、PrintWriter
相比普通的OutputStream和Writer增加了print()和println()方法,这两个方法可以输出实参的toString()方法的返回值
这两个类还提供自动flush()的功能
Ÿ 操作对象
ObjectOutputStream
可以将实现了Serializable的接口的对象转成字节写出到流中
ObjectInputStream
可以从流中读取一个ObjectOutputStream流写出的对象
Ÿ 操作内存缓冲数组
ByteArrayOutputStream: 写出到字节数组(内存)中,可以获取写出的内容装入一个字节数组。通常我们用这个流来缓冲数据。
ByteArrayInputStream:可以从一个字节数组中读取字节。
CharArrayWriter:写出字符到字符数组(内存)中,可以获取写出的内容装入一个字符数组。
CharArrayReader:可以从一个字符数组中读取字符。
Ÿ 管道流
PipedInputStream:管道输入流,可以从管道输出流中读取数据
PipedOutputStream:管道输出流,可以向管道输入流中写出数据
Ÿ 操作基本数据类型
DataInputStream、DataOutputStream
可以按照基本数据类型占用空间大小读写数据
Ÿ 随机访问文件
RandomAccessFile
5. 多线程
5.1. 多线程概念
Ø 线程与进程
Ÿ 进程就是一个运行中的程序。
Ÿ 一个进程中可以有多个线程,线程是CPU调度和分派的基本单位。我们可以理解为线程就是程序运行中的一条路径。
Ø 多线程存在的意义
Ÿ 允许多个线程并发执行,提高程序运行效率。
Ÿ 例如:迅雷多线程下载,QQ多个人同时聊天,凌波多个人同时共享屏幕。
5.2. 线程的使用
Ø 创建线程有两种方式
Ÿ 自定义一个类继承Thread类,将线程要做的事写在run()方法中,由于子类可以当父类来用,创建自定义子类对象就是创建了一个线程。
Ÿ 自定义一个类实现Runnable接口,将要做的事写在run()方法中。创建Thread对象时在构造函数中传入Runnable实现类对象。
Ø 线程的启动
Ÿ 两种创建方式都是调用Thread对象的start()方法。
Ÿ 当调用start()方法时,CPU会开启一条新线程,并在新线程上执行run()方法。
Ø 线程常用方法
Ÿ currentThread
静态方法,用来获取当前线程
Ÿ getName、setName
用来获取、设置当前线程的名字
Ÿ sleep
控制线程休眠,单位为毫秒
Ÿ setDeamon
将线程设置为守护线程。线程默认是非守护线程,守护线程不能单独执行。
Ÿ join
当前线程暂停,等待加入的线程运行结束,当前线程继续执行。
5.3. 多线程同步
Ø 线程安全问题
Ÿ 多线程并发访问同一数据,有可能出现线程安全问题。
Ÿ 一条线程的访问还没有结束,CPU切换到另一条线程工作,导致数据访问出错。
Ø 使用同步解决线程安全问题
Ÿ 使用同步代码块synchronized(锁对象){需要同步的代码...}形式将访问数据的代码锁住,在同步代码块中的内容同一时间内只能一个线程执行。
Ÿ 使用同步方法,用synchronized修饰方法,整个方法的代码都是同步的,只能一个线程运行。同步方法使用this作为锁。
Ø 死锁
Ÿ 在多个线程并发执行使用多个锁来同步时,有可能互相冲突,导致程序无法继续执行。
Ø 同步的优点与缺点
Ÿ 同步可以解决多个线程同时访问一个共享数据的问题,只要加上同一个锁,在同一时间内只能有一条线程执行。
Ÿ 在执行同步代码时每次都会判断锁,非常消耗资源,效率较低。
5.4. 多线程通信
Ÿ 在同步代码中可以使用锁对象的wait()方法让当前线程等待
Ÿ 使用锁对象的notify()方法可以将正在等待的线程唤醒
Ÿ 如果多个线程都在等待,notify()唤醒随机1个
Ÿ notifyAll()方法可以唤醒所有在等待的线程
5.5. JDK5之后的线程同步与通信
Ø 同步
Ÿ 使用java.util.concurrent.locks.Lock接口的实现类对象来进行同步
Ÿ ReentrantLock就是Lock的实现类,可以实现synchronized的功能
Ÿ 在需要同步的代码块前后使用lock()和unlock()方法来完成同步
Ÿ unlock()最好放在finally中,因为如果上面代码抛出异常没有解锁的话,会导致其他线程无法运行,程序卡死。
Ø 通信
Ÿ 使用Lock对象的newCondition()方法获取一个Condition对象,Condition对象可以控制指定线程的等待与唤醒。
Ÿ await()方法可以控制线程等待。
Ÿ signal()方法可以唤醒等待的线程。
Ÿ signalAll()方法可以唤醒所有等待线程。
6. GUI
6.1. GUI概念
Ø 什么是GUI
Ÿ GUI是Graphical User Interface的缩写,图形化用户界面
Ø awt和swing
Ÿ Java为GUI提供的对象都存在java.awt,javax.swing两个包中
Ÿ awt依赖于本地系统平台,如颜色样式显示
Ÿ swing跨平台
Ø 组件与容器
Ÿ 组件 Component,是GUI图形界面的组成单元。
Ÿ 容器Container,可以存放组件,也可以存放容器。
6.2. 布局管理
Ø FlowLayout(流式布局管理器)
Ÿ 从左到右的顺序排列。
Ø BorderLayout(边界布局管理器)
Ÿ 东,南,西,北,中
Ø GridLayout(网格布局管理器)
Ÿ 规则的矩阵
Ø CardLayout(卡片布局管理器)
Ÿ 选项卡
Ø GridBagLayout(网格包布局管理器)
Ÿ 非规则的矩阵
6.3. 建立一个窗体
Ÿ 窗体中可以存放各种组件,所以窗体是容器Container。创建时我们使用的是它的子类
Ÿ Container的常用子类有两个,Window和Panel。Window是我们常用的窗体,Panel是用来布局的不可见的。
Ÿ Window也有两个常用子类,Frame和Dialog。Frame是我们常用的带有标题和边框的顶层窗口,Dialog是对话框。
Ÿ 所有AWT包中的类都会运行在AWT线程上
6.4. 事件处理
Ø 事件处理机制
Ÿ 事件:用户对组件的一个操作。
Ÿ 事件源:发生事件的组件。
Ÿ 监听器:我们需要处理某个事件,就需要在发生事件的组件上添加监听器,也就是java.awt.event包中XxxListener接口的子类。
Ÿ 事件处理器:监听器中的方法。监听器被添加在组件上之后,组件上发生了对应事件就会执行指定方法。
Ø 常用事件分类
Ÿ 窗体事件,WindowEvent,窗体打开、关闭、正在关闭、激活、最小化等。
Ÿ 鼠标事件,MouseEvent,鼠标按下、抬起、进入、移出等。
Ÿ 键盘事件,KeyEvent,键盘按下、抬起等。
Ÿ 动作事件,ActionEvent,在某一组件上发生了定义好的动作,例如按钮上鼠标点击或按空格,菜单上鼠标点击或按回车等。
7. Socket网络编程
7.1. 网络编程概念
Ø IP地址
Ÿ 每台网络终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址。
Ÿ ipconfig:查看本机IP
Ÿ ping:测试连接
Ÿ 本地回路地址:127.0.0.1
Ÿ IPv4:4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿。已经用尽。
Ÿ IPv6:8组,每组4个16进制数。
1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f
1a2b::aaaa:0000:0000:0000:aabb:1f2f
1a2b:0000:aaaa::aabb:1f2f
1a2b:0000:aaaa::0000:aabb:1f2f
1a2b:0000:aaaa:0000::aabb:1f2f
Ø 端口号
Ÿ 每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器上,还要明确发到哪个程序。
Ÿ 端口号范围从0-65535
Ÿ 编写网络应用就需要绑定一个端口号,尽量使用1024以上的,1024以下的基本上都被系统程序占用了。
Ÿ 常用端口
mysql: 3306
oracle: 1521
web: 80
tomcat: 8080
QQ: 4000
feiQ: 2425
Ø 网络协议
Ÿ 为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
Ÿ UDP
面向无连接,数据不安全,速度快。不区分客户端与服务端。
Ÿ TCP
面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
Ø Socket
Ÿ 通信的两端都有Socket。
Ÿ 网络通信其实就是Socket间的通信。
Ÿ 数据在两个Socket间通过IO传输。
Ÿ Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和port。
7.2. UDP传输
Ø 发送
Ÿ 创建DatagramSocket
Ÿ 创建DatagramPacket
Ÿ 使用DatagramSocket发送DatagramPacket
Ÿ 关闭DatagramSocket
Ø 接收
Ÿ 创建DatagramSocket
Ÿ 创建DatagramPacket
Ÿ 使用DatagramSocket接收DatagramPacket
Ÿ 关闭DatagramSocket
7.3. TCP传输
Ø 客户端
Ÿ 创建Socket连接服务端
Ÿ 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的管道流
Ÿ 输入流可以读取服务端输出流写出的数据
Ÿ 输出流可以写出数据到服务端的输入流
Ø 服务端
Ÿ 创建ServerSocket
Ÿ 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
Ÿ 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的管道流
Ÿ 输入流可以读取客户端输出流写出的数据
Ÿ 输出流可以写出数据到客户端的输入流