Java学习笔记
Java学习笔记
JJuprising错题
通过super可调用父类构造函数。对
构造函数的返回类型只能是void型。错,造函数必须与类名相同且没有返回值,void是空返回值并不是无返回值所以是错的
一般在创建新对象时,系统会自动调用构造函数。对
【单选题】下面赋值语句不合法的是___D___。
A.Long a=(Long)(long)3;
B.Long b=3L;
C. Long c=Long.parseLong(“3”);
D.Long d=(Long )3;
下面赋值语句不合法的是 D。在Java中,”Long”类是原始数据类型long的包装类,必须使用关键字”new”来构造包装类,才能创建有效的对象。从长值3创建Long对象的正确方法如下:
1
Long d = new Long(3);
其他三个选项都是从长值3创建Long对象的有效方法。选项A从将整数值3转换为长值,然后再转换为Long的结果创建Long对象。选项B从长值3L创建Long对象。选项C通过调用Long类的parseLong方法,从字符串值”3”创建Long对象。
【单选题】java语言中,在定义类时不能使用的修饰符是____B______。 A.public B.private C.abstract D.final
- 答案是 B:private。在 Java 语言中,private 是一种访问修饰符,它只能在类的内部使用,不能用于定义类。
- A 选项:public。public 是一种访问修饰符,它表示在任何地方都能够访问。定义类时可以使用 public 修饰符。
- C 选项:abstract。abstract 是一种修饰符,它用于定义抽象类和抽象方法。定义类时可以使用 abstract 修饰符。
- D 选项:final。final 是一种修饰符,它表示类不能被继承,方法不能被重写。定义类时可以使用 final 修饰符。
在Java语言中,下面关于Math类的常见操作不正确的描述是_____D__B___。
A.执行Math.ceil(-10.5) 语句的结果是-10.0
B.执行Math.round(10.5) 语句的结果是11.0 (答案是11,没有小数点!)
C.执行Math.floor(-10.5) 语句的结果是-11.0
D.执行Math.round(-10.5) 语句的结果是-10
Math.round
不完全是四舍五入,当刚好为负数且刚好0.5,舍入到正无穷方向上的整数。如Math.round(-20.5)
结果为-20
【单选题】执行下面程序段后,输出结果是___C______。
int a=4,b=6,c=8;
System.out.println(++a*b—c );
A.11
B.16
C.22
D.23
注意后面的—前两个应该是b的后缀,而不是后两个是c的前缀,由于是后缀,无影响,而a的前缀加了用,因此是5×6-8结果为22,而且b的值变为5,a为5。
下面概念中,不属于面向对象程序设计的是_____A_____。
A.过程调用
B.对象
C.类
D.继承
文本框获得焦点时回车和按钮单击,都属于ActionEvent事件,也就是说文本框和按钮可以作为ActionEvent事件的事件源。
而选择框的选中,和下拉列表的选中,都是在触发ItemEvent事件。
不同类型的事件的监听器要实现的接口不同,对于ActionEvent事件,这个接口是 ActionListener,实现其中的actionPerformed方法,方法传入的也是ActionEvent对象。
而对于ItemEvent事件,则要实现的是ItemListener接口,实现其中的itemStateChanged方法,方法传入的是ItemEvent对象。
下面关于java.sql包中接口和类的描述不正确的是__B__。
A.Connection 接口:表示数据库连接
B.DriverManager类:表示驱动器 (错,JDBC 的管理层,作用于用户和驱动程序之间。)
C.ResultSet接口:表示SQL查询语句返回的结果集
D.Statement接口:负责执行SQL语句
在Java语言中,下面用于执行存储过程SQL语句的是___B___。
A.Statement
B.CallableStatement
C.createStatement
D.PreparedStatement
Statement 对象有三种:(Statement)对象用于执行不带参数的简单 SQL语句; (PreparedStatement)对象继承Statement,用于执行带或不带参数的预编译 SOL语句:(CallableStatement) 对象继承PreparedStatement,用于执行对数据库存储过程的调用
在Java语言中,下面关于Scanner类描述错误的是_____D__C___。
A.Scanner类可以方便的完成输入流的输入操作
B.Scanner sc=new Scanner(System.in);//从标准输入中扫描
C.Scanner类位于javax.util包中,使用时需要import导入**(是java.util)**
D.Scanner可以扫描指定的文件.
D是对的,C是错的。
在Java语言中,下面不属于ComponentEvent的子类是____D______。
A.InputEvent
B.FocusEvent
C.WindowEvent
D.ItemEvent
ItemEvent不属于ComponentEvent的子类。
在Java语言中,下面关于组件定义错误的是____ D_____。
A.TextField tf=new TextField(3);//int型指定列宽
B.Timer tr=new Timer();
C.JFileChooser jf=new JFileChooser();
D.TextArea ta=new TextArea(3);
在Java语言中,以下____C____项是接口B的正确定义。
A.interface B{ void print(){ };}
B.abstract interface B{void print(){}}
C.interface B {void print();}
D.interface B extend A { void print(){}}//A为已定义接口
1
2
3
4
5public interface Paintable{
void draw();//没有{},可省略public abstract关键字
}
interface intf1{}
interface intf2 extends intf1{}//接口继承接口下面概念中,不属于面向对象程序设计的是_____A_____。
A.过程调用
B.对象
C.类
D.继承
在Java语言中,成员变量中被static关键字修饰的变量,叫 B
A.变量
B.类变量 (静态变量的成员变量)
C.实例变量
D.整型变量
在Java语言中,下面关于String类的常见操作不正确的描述是______B____。
A.假设
s ="class"
;则执行char c = s.charAt(1)
语句后变量c的值是l
B.
indexOf
方法是查找特定字符或字符串在当前字符串中的起始位置,如果不存在则返回0 。(返回-1)C.
concat
方法的作用是进行字符串的连接,将两个字符串连接以后形成一个新的字符串D.
equals
方法的作用是判断两个字符串对象的内容是否相同charAt()
方法用于返回指定索引处的字符。索引范围为从0
到length() - 1
。下面关于try catch语句中异常类排列顺序正确的说法是____B______。
A.父类异常在前,子类异常在后
B.父类异常在后,子类异常在前
C.父类和子类异常排列顺序前后无影响
D.只能有子类异常
已知Integer.MAX_VALUE 的值为2147483647,在执行“Integer max1=Integer.MAX_VALUE,max2= max1+1;”语句后,max2等于____A______。
A.-2147483648
B.2147483647
C.0
D.2147483648
在Java语言中,Person类有一个成员变量age被protected修饰,下面关于age说法不正确的是___C_______。
A.能被Person的子类访问。
B.能被Person类所在同一个包中的其它类访问。
C.能被Person类所在包之外的其它类访问。
D.不能被Person类所在包之外的其它类访问。
protected 访问控制符能被用于方法和成员变量
声明为protected的方法和成员变量能被同一个包里的所有类所访问,就像默认修饰符package一样
能被该类的子类所访问,子类可以和父类不在一个包中。
另一个包中的子类只能通过子类或其子类的引用来访问父类中受保护的成员。同一包中的子类没有此限制。这样可以确保来自其他包的类只访问属于其继承层次结构一部分的成员下面哪项不属于Statement接口提供的3个执行SQL语句的方法______A____。
A.executeDelete(String sql)
B.executeUpdate(String sql)
C.executeQuery(String sql)
D.execute(String sql)
在Java语言中,下面关于RandomAccessFile描述错误的是_____D_____。
A.实现DataInput和DataOutput接口
B.getFilePointer()方法:返回此文件中的当前偏移量
C.readFloat()方法:从此文件读取一个 float
D.writeChar(int v):按双字节值将char写入该文件,先写低字节(将一个字符作为一个两个字节的值写入基础输出流,其中高字节在前。)
在Java语言中,下面相关描述错误的是____B______。
A.File类对象对应于系统中的一个目录或文件
B.CharArrayReader 是一个把字符数组作为源的输出流的实现.(输入流)
C.FileInputStream:以字节流方式读取
D.FileReader:把文件转换为字符流读入
下面关于Java事件描述错误的是_____A_____。
A.只有外部操作会产生事件
B.可以通过继承EventObject类编写自定义事件类
C.事件处理的三要素包括事件源、事件以及事件监听器
D.要在事件源上注册事件监听器
在Java语言中,下面关于Applet描述错误的是A。
A.Applet能执行任何本地计算机上的程序(错误)
B.Applet的生命周期中有四个状态:初始态、运行态、停止态和消亡态
C.Applet的init()方法在Applet的生存周期中只调用一次
D.Applet应用程序必须嵌入在HTML页面中,才能得到解释执行
此外,Applet是Java类,且通常情况下不能进行文件的I/O操作
在Java语言中,下面关于List不正确的描述是_______B___。
A.List是在java.util包中
B.List是一个类(是接口)
C.List具有get(int index)方法
D.List是一个接口
List,Set,Map都是接口
在Java语言中,类Double定义在以下的哪个包中_____C_____。
A.java.io
B.javax.lang
C.java.lang
D.java.util
在Java语言中,下面关于接口错误描述的是___A___。
A.接口不仅包括方法的特征,还有方法的实现。
B.接口只允许public 和abstract修饰。
C.接口中的属性只能被public 、final、static修饰。
D.一个类可以实现多个接口。
接口中的属性只能被public 、final、static修饰,而且必须赋值,因为是常量,在后面不能改变,否则会报错,不会给默认值的
在Java语言中,执行下列程序段后,i的结果是____D______。
int i;
for(i=0;i<10;i++)
{
if (i>4){ continue;}// 一直跳过
if(i>7 ){ System.out.println(i); break;}
}
A.6
B.8
C.9
D.10
在Java语言中,下面关于颜色定义不合法的是___B_______。
A.Color c1=new Color(0xffffff)
B.Color c2=new Color(Color.BLUE)
C.Color c3=new Color(0,0,255)
D.Color c4=new Color(0.2f,0.6f,1.0f)
Color 是 Java 中的一个类,可以用来表示颜色。在 Java 中,可以使用以下几种方法来定义颜色:
- 使用 16 进制 RGB 值来定义颜色,例如 A.Color c1=new Color(0xffffff)。
- 使用 24 位 RGB 值来定义颜色,例如 C.Color c3=new Color(0,0,255)。
- 使用浮点型 RGB 值来定义颜色,例如 D.Color c4=new Color(0.2f,0.6f,1.0f)。
B.Color c2=new Color(Color.BLUE) 中的 Color.BLUE 是预定义的颜色常量,它表示蓝色。这种方式并不能用来定义颜色,因此 B 选项是不合法的。
下面不属于Java语言中常见事件类型的是____C______。
A.KeyEvent
B.MouseEvent
C.TouchEvent
D.ItemEvent
在Java语言中,下面不符合数组定义格式的是___D_______。
A.int []a=new int [3];
B.int b[]={1,2,3};
C.int c[]=new int [3];
D.int e[3]=new int [3];
在 Java 中,数组是用于存储一组相同类型的数据的数据结构。在 Java 中,可以使用以下几种方法来定义数组:
- 使用 new 运算符来定义数组,例如 A.int []a=new int [3]; 和 C.int c[]=new int [3];。
- 使用 {} 来定义数组并初始化数组元素,例如 B.int b[]={1,2,3};。
在Java语言中,下面变量命名不合法的有 C
A.$fn
B.p5p
C.static
D._user
必须以字母、下划线、或者美元符$开头;
在Java语言中,下面不属于JDBC的主要功能是A
A.解析SQL语句
B.处理数据库的返回结果
C.建立与数据库或者其他数据源的连接
D.向数据库发送SQL命令
在Java语言中,下面用于执行简单的不带参数的SQL语句是 A
A.Statement
B.PreparedStatement
C.CallableStatement
D.createStatement
定义int A=5,执行“System.out.println(“a=”+((A<5)?5.1:4));” 语句的结果是 B
A.a=5.1
B.a=4.0
C.a=5
D.a=4
三目运算符后面类型不同需要类型升级
在Java语言中,下面关于包描述不正确的是 C
A.包提供了访问权限和命名的管理机制
B.包是Java提供的一种区别类的名字空间的机制
C.类只能访问其所在包中的所有类
D.包是类的组织方式,是一组相关类和接口的集合
(1)具有public权限的类能被所有包中的类访问,与所在的包无关(2)具有缺省权限的类只能被所在包中的类访问,不能再其包外访问
定义char x=’a’,下面赋值语句不合法的有 B
A.float b=x;
B.byte c=x;
C.double d=x;
D.int a=x;
应该为 byte c=(byte)x;
在Java语言中,下面关于异常的错误描述是_____D_____。
A.异常是java提供的用于处理程序中错误的一种机制
B.java.lang. Exception类是所有异常的父类
C.java.lang.NullPointerException是空指针异常类
D.当异常产生时,程序会自动跳转到异常处理程序
在Java语言中,下面关于File类描述错误的是 A
A.执行File f=new File(“e:\txx.txt”)语句的结果是在e盘上创建了一个txx.txt文件
B.File类对象对应于系统中的一个目录和文件
C.File类对象描述文件名、可否读写等属性,但不读写文件
D.一旦创建,File对象表示的抽象路径名将不会改变
File f=new File;创建的是一个对象
在Java语言中,下面关于AWT组件描述错误的是 C
A.Choice:制作用于单选的下拉列表
B.与菜单相关的类主要有三个: MenuBar、Menu、Menultem
C.Panel类可作为容器容纳其它组件,也可以独立存在
D.Canvas:代表屏幕上一块空白的矩形区域
Panel类可作为容器容纳其它组件,也可以独立存在必须在窗体容器中使用,无法脱离窗体显示
substring()
截取字符串,从索引0开始计数1
2
3
4
5
6
7
8
9
10String Str = new String("This is text");
System.out.print("返回值 :" );
System.out.println(Str.substring(4) );//4开始到最后
System.out.print("返回值 :" );
System.out.println(Str.substring(4, 10) );//含头不含尾
//结果
返回值 : is text
返回值 : is tepublic int index0f(int ch,int fromlndex)
: 返回从fromlndex
位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。编译JavaApplication源程序文件将产生相应的字节码文件,这些字节码文件的扩展名为D
A. .html
B. .Java
C. .exe
D. .class
字符串比较。Java中,使用”==”比较字符串时,判断的是两个字符串是否存放在相同的位置。
1
2
3
4
5
6
7
8例如:x = "Hello"; y = "Hello";
x == y; //就是True
x == "Hello"; //也是True
如果 String z=new String(x);
x==z;//结果就是false在Java语言中,关于final修饰符的说法不正确的是 C
A.fnal成员变量表示常量,只能被赋值一次,赋值后值不再改变
B.final类不能被继承,没有子类,fnal类中的方法默认是final的
C.final能用于修饰构造方法
D.final方法不能被子类的方法覆盖,但可以被继承
final修饰的类,为最终类,该类不能被继承。如String 类;final修饰的方法可以被继承和重载,但不能被重写、覆盖;final修饰的变量不能被修改,是个常量
main是static,所以不能直接调用非静态的方法
方法重载就是一个类中有多个同名但有不同形参和方法体的方法 对
Java String类 trim() 方法用于删除字符串的头尾空白符
大题模板
集合类
ArrayList
1 | List<String> list=new ArrayList<>(); |
TreeSet
截取部分输出 it=tree.SubSet(头,尾).iterator();
it=tree.headSet(边界).iterator();
1 | TreeSet<UpdateStu>tree =new TreeSet<>(); |
文件存取
字节流创建–输入–读取
1 | File file=new File("MyFile.txt"); |
写入文件:
1 | FileOutputStream outputStream=new FileOutputStream(file);//创建输出流 |
FileOutputStream里放file,准备byte[]是字符串.getBytes(),写入用write
读取
1 | FileInputStream inputStream=new FileInputStream(file);//准备输入流 |
读取用read,返回值是长度
文件信息
1 | System.out.println("文件长度:"+file.length()+"字节"); |
(缓存)字符流
写入
1 | FileWriter fw=new FileWriter(file); |
FileWriter里放file,Buffered里放FW,写入用write,换行符newLine()
读取
1 | FileReader fr=new FileReader(file); |
FileReader里放file,BufferedReader里放FR,读取每一行用br.readLine(),字符串存
Swing
事件监听
1 | class MyJDialog extends JDialog{ |
组件.addAcitonListener里边new Actionlistener
多线程
消费生产栈
1 | class ms{ |
网络通信
TCP 双向通信
服务器端
接收用BufferReader
1 | class MySever{ |
socket.getInputStream就是文件存取的file,类比一下,而InputStreamReader就是FileReader
客户端
发出用PrintWriter
1 | class MyClient{ |
connect里:绑定端口指定ip,准备流
构造里:writer.println传数据
UDP
服务器端
1 | //指定地址 |
构造里边配置:getName获取指定地址,实例化MulticastSocket绑定端口,socket加入组
run()里边:准备包,字符转字节数组,实例化DatagramPacket,socket.send(packet)
客户机端
1 | class Receive implements Runnable{ |
构造里边:构造里边配置:getName获取指定地址,实例化MulticastSocket绑定端口,socket加入组
run()里边:准备字节数组,实例化DatagramPacket,socket.receive(packet),然后new String(packet.getData(), packet.getLength())packet转字符
main函数当作类外的函数来看待
1、包内访问权限和protected有何不同?(p98)
包内访问权限介于private和protected之间
包外的派生类,可以在派生类内部调用基类的protected成员
包外的派生类,无法在派生类内部调用基类的包内访问成员
- 当两个包在同一个项目之中时,可以通过完整类目继承包外的基类访问
1 | package Lab2; |
- 当两个包在不同的项目之中时,将基类项目导出为.jar,将该.jar文件复制到派生类所在的项目文件夹中,然后右键点击选择”add building path”添加到构建路径,然后代码与上面相同。
2、所有数组都能排序吗?
错误。排序要有一定依据,没有指定依据无法排序。如类型为类的数组,可比较的属性不止一种(implements比较器)。
3、接口
接口的本质是标准,是设计者、实现者,调用者之间的桥梁
类内实现的可比较器Comparable,由被比较的类implements实现,重写
compareTo
函数类外实现的可比较器Comparator,由另外一个类implements实现,重写
compare
函数- 如果是一次性的考虑用匿名内部类来实现比较器。否则这个只用一次的有名字的类可能会对代码理解造成困扰。
基本输入输出范例代码
1 | Scanner sc=new Scanner(System.in); |
第四章 流程控制
循环语句
foreach语句
1 | for(元素类型x:遍历对象obj){ |
例子:遍历一维数组
1 | public class Repetition{ |
第五章 数组
数组的基本操作
数组排序
Arrays.sort(arr);
Arrays.parallelSort(arr);
多线程排序,数据量大于一百万
复制数组
copyof()方法
语法:int a[]=Arrays.copyOf(arr,int newlength);
- newlength:复制后新数组的长度
!注:不能直接
a=b
,数组名是指针常量(常指针)
第六章 类和对象
面向对象概述
封装
- 避免外部操作对内部数据的影响,提高程序的可维护性
- 提高工作效率,把无需调用者关心的内容隐藏,简化编程,知道面对外部的接口能调用即可
类
对于人来说,
public:学历、知识(别人抢不走的)
protected:身体等
public:很多
protected同包其他类或子类(继承)可见,其他包的类或子类不可见;private都不可见,只有本类可见。
this 关键字
this关键字用于表示本类当前的对象,只能在本类中使用。
1 | public void setName(String name){//定义一个setName()的方法 |
类的构造方法
Java类内的属性值不支持默认值,不能直接定义
int count=0
应使用默认构造函数初始化
1 | public class eggCake{ |
静态
1 | public class Lab2_1{ |
类内静态成员共用一份空间
如果函数
对象
对象的销毁
1 | public class Lab2_1{ |
第七章 继承、多态、抽象类与接口
类的继承
extends 关键字
语法:CHild extends Parents
super 关键字
Object 类
Object类是一切类的基类,隐含的继承
如果没声明,toString()一定是调用自Object类,输出是字符编号。
输出字符串自动会调用toString()函数,应当重写以达到需要的输出目的。
重写只能保持或扩大访问权限,如原本是Public不能改成Private。
1 | public class Student{ |
对象的类型转换
需要基类对象的任何地方,都可以用派生类对象替代
向上转型
向下转型
instanceof关键字判断对象类型
方法的重载
函数的返回值类型不属于重载的依据
final 关键字
最终的、终态
多态
抽象类与接口
抽象类
- 只要类中有一个抽象方法,此类就是抽象类
- 抽象类不能实例化,抽象类存在的目的就是为了被继承
- c++中全是抽象方法就叫纯虚类
接口
- 只能声明,不能实现
第9章 异常处理
异常与错误:
一个不好的问题发生了,如果对该问题提前有应对措施,就是异常处理;
如果没有任何准备,就是错误。
1 | try{ |
第10章 字符串
String类,字符常量存储。
创建
1 | char a[]={'g','o','o','d'}; |
截取
1 | char a[]={'g','o','o','d'}; |
字符串连接
int+''
把int
转为String
类型
获取字符串信息
1 | System.out.println(s[0]);//是错误的 |
字符串的查找
indexOf(String s)
区分大小写
1 | String str="We are students"; |
字符串操作
获取字符串
substring(int beginIndex)
1 | String str="Hello World"; |
字符串替换
replace()
replaceAll()
支持正则表达式
判断相等
equals()
而不是用==
1 | String s1="abc"; |
如果直接等号赋值,就是基本数据类型,用==
可以判断;当用new
,把变量当对象来看待,两个对象不可能相等,因此只能用equals()
来判断相等。
equals在基本数据类型比较的是值,引用数据类型对象、数组、函数比较的是地址,如果要比较值需要重写equals。String是已经重写好equals了的
没重写之前两者都是比较地址,重写之后前者比较地址后者比较值
比如我们写一个person类,根据姓名来判断两个person类实例对象是否相等。
1 |
|
正则表达式
1 | String regex1="[a-zA-Z_$]+[a-zA-Z_$]*";// |
使用:
1 | package lesson5; |
元字符
检索特殊字符要用转义符号\\
,在java的正则表达式中两个\\
代表其他语言一个\
字符匹配符
符号 | 含义 | 实例 | 说明 | 匹配输入 |
---|---|---|---|---|
[ ] |
匹配任意一个 | [efgh] |
e,f,g,h任意一个 | e,f,g,h |
[^ ] |
排除 | [^abc] |
除了abc之外的任意一个字符包括数字和特殊符号 | d,f,p |
. |
匹配除\n以外的任何字符 | a..b |
a开头b结尾中间任意两个字符 | aaab,a#*b |
\\d |
匹配单个数字字符相当于{0-9} | \\d{3}{\\d}? |
包含3个或4个数字的字符串 | 123,9876 |
\\D |
匹配单个非数字字符,相当于[^0-9] |
\\D{\\d}* |
以单个非数字字符开头后接任意个数字的字符串 | a,A342 |
\\w |
匹配单个数字、大小英文写字母,下划线,相当于[0-9a-zA-Z_] |
\\d{3}\\w{4} |
以3个数字字符开头的任意长度为7的数字字母字符串 | 234abcd、1234Pe |
\\W |
匹配单个非数字、大小写字母和下划线字符,相当于[^0-9a-zA-Z_] |
\\W+\\d{2} |
以至少1个非数字字母字符开头,2个数字字符结尾的字符串 | |
\\s |
匹配任何空白字符(空格,制表符等) | |||
\\S |
匹配任何非空白字符 | |||
\\. |
匹配除\n之外的所有字符 |
区分大小写
默认区分大小写,如模式串写"abc"
匹配出来abc而(?i)abc
表示不区分大小写,a(?i)bc
是bc不区分大小写
常用类库
Integer类
能在int类型和String类型之间互相转换。
1 | int num = Integer.parseInt("456");//返回包含在由str指定的字符串中的数字的等价整数值 |
Double类
是Number类的子类,都是对浮点数进行操作。Double类在对象中包装一个基本类型为double的值,每个Double类的对象都包含一个double类型的字段。可将String和double相互转换。
1 | Double dNum=Double.valueOf("3.14"); |
Boolean类
当 String 的参数值在不区分大小写的时候等于 “true” ,则 Boolean.valueOf(String) 返回值为 true;
1 | Boolean b1=Boolean.valueOf("true"); |
Character类
字符大小转小写
1 | Character mychar1=Character.valueOf('A');//返回保存指定char值的Character对象 |
第12章 集合类
graph LR A[集合类]-->集合类概述 A-->Collection接口 A-->List集合 A-->Set集合 A-->Map集合
集合类概述
集合与数组
容器 | 数组 | 集合 |
---|---|---|
长度 | 长度固定 | 长度可变 |
存放的东西 | 存放基本数据类型 | 存放对象的引用 |
graph LR HashMap-->A[Map] TreeMap-->A HashSet-->B[Set] TreeSet-->B ArrayList-->C[List] LinkedList-->C C-->D[Collection] B-->D A-->Java.lang.Object D-->Java.lang.Object
Collection 接口
1 | Collection<类名> list=new ArrayList<>();//尖括号只能呢是类,比如不能放int要放integer |
方法:
add(E e)
remove(Object o)
isEmpty()
iterator()
size()
返回int型
遍历集合通过迭代器(Iterator)来实现,只读且向前。Collection接口中的iterator()方法可返回在此Collection进行迭代的迭代器。
可以用foreach,可读可写,但是不能break,除非抛出异常。遍历修改迭代器(ListIterator)
1 | import java.util.*; |
List集合
List集合中的元素允许重复,各元素的顺序就是对象插入的顺序。类似Java数组,用户通过使用索引(元素在集合中的位置)来访问集合
List接口
继承Collection接口,包含其所有方法。还定义两个重要的方法:
get(int index)
:获取指定索引位置的元素set(int index,Object obj)
:将集合中指定索引位置index
的对象修改为指定的对象obj
List接口的实现类
属于有序集合,不是自动排序的意思
ArrayList
类 可变的数组,允许重复 允许nullLinkedList
类链表结构保存对象
类 | ArrayList |
LinkedList |
---|---|---|
优点 | 根据索引快速访问 | 便于向集合插入和删除对象 |
缺点 | 插入或删除对象速度较慢 | 随机访问效率较低 |
动态数组,索引存取
链表,存取有序,不是存到链表头就是链表尾
实例化
1 | List<E> list=new ArrayList<>(); |
开头是List,后面别忘了<>
Set集合
Set
集合传入的Collection
对象不能有重复值
Set接口实现的类:
HashSet
类,由哈希表(HashMap实例)支持。允许nullTreeSet
类,还实现了Java.util.SortedSet接口
类 | HashSet |
TreeSet |
---|---|---|
区别 | 不保证Set集合的迭代顺序和顺序的恒久不变 | 按自然顺序递增,也可按比较器实现排序 |
1 | Set<类名> set=new TreeSet<>(); |
必须可比较,传入的对象的类必须是包装类(默认字典顺序)或者实现comparable
接口的类
HashSet哈希存储,计算哈希值散列导不同位置,存取位置不能保证,效率高
TreeSet树存储,按照树结构对元素进行比较,放到合适位置,这也就说明,元素会按照树的性质去存储,那么也就无法保证存和取元素的顺序。但是元素可以在存储的时候根据自身的大小排好序,从而可以很轻易的找到最大值,最小值,以及给定一个元素,找到比他大和比他小元素等操作。
问:在定义对象类型时,应该定义为基类或接口的类型,还是派生类的类型?
创建的时候类型不确定,先定义为基类;或如果定义为接口给别人调用就声明为基类。要专门调用派生类具有的功能直接声明为派生类。
但是定义为基类无法调用子类特有的成员,如
subSet()
是TresSet
特有的,定义为基类时无法调用,除非强制转型为子类。1
2Set<Integer> set=new TreeSet<>();
TreeSet set2=((TreeSet<Interger>)set.)subSet(3,10);
TreeSet增加的方法:
- first() 返回此Set集合第一个(最低)元素
- last() 返回当前最后一个(最高)元素
- comparator() 返回进行排序的比较器,若自然顺序则null
- headSet(E toElement) 返回一个新Set集合是toElement对象(不包含)之前的所有对象
- subSet(E fromElement,E toElement) 返回Set集合是fromElement对象与toElement之间的所有对象,含头不含尾
- tailSet(E fromElement) 返回包含fromElement之后所有对象
含头不含尾
Map集合
没有继承Collection接口,每个对象是键值(<key,value>)的形式。
每个key只能映射一个value;类要可比较;iterator()的next()输出的仅是key值
Map接口除集合方法的特殊方法
- put(K key,V value)
- containsKey(Object key) 若包含指定key的映射关系返回true
- containsValue(Object value) 若将一个或多个key映射到指定值,返回true
- get(Object key) 返回对象对应的值,否则null
- values() 返回该集合所有值对象形成的Collection对象,用iterator()遍历输出
类 | HashMap | TreeMap |
---|---|---|
特点1 | 允许nul值和null键,键唯一 | 不允许值对象null(要排序的原因) |
映射 | 通过哈希表 | 具有一定顺序 |
优缺 | 不保证顺序不变;快速访问 | 添加、删除、定位性能差;顺序排序 |
运用的时候使用HashMap类实现Map集合,当需要顺序输出时再创建一个完成相同映射关系的TreeMap类实例
1 | Map<String,String> map=new HashMap(); |
如果key传入的是像Integer,String这样本身有序的,就会按字典序排列,而不是按哈希码。
原理:add()
时用hashcode
找哈希地址,用equal()
看是否有存东西。如果是false
就先并排放;若是true
说明有了不用重复存。取值的时候找哈希地址,如果存在多个用equal()
取具体的那一个。以上哈希码相同的情况为哈希冲突,同一个哈希地址可以存放多个不同对象。
优点:不用全部遍历,找到哈希地址再判断哪个是需要的取出即可。
第13章 枚举类型与泛型
将“填空题”变为“选择题”
1 | //声明为int/String类型方便switch case用 |
问:接口和枚举如何选择?
- 接口一般是给别人来实现,功能可以更强大,如果不需要实现直接用枚举就行。
- 枚举优点:简单,运行效率高,类型安全
枚举类型中的构造方法
在枚举类型中,可以添加构造方法,但是规定这个构造方法必须被private修饰符所修饰。用于提示枚举值更加详细的含义、
泛型
向上向下转型
1 | 父类 a=new 子类();//向上转型 |
例子:
1 | public class Test{ |
定义泛型类
Object
类为最上层的类,为了通用通常使传入的值与返回的值都以Object
类型为主(Object
太大了,不能统统用Object
类)。当需要使用这些实例时,必须正确地将该实例转换为原来的类型,否则运行时将会发生ClassCaseException
为了预防,Java
提供泛型机制:
1 | 类型<T> |
高级用法
泛型限制
对泛型类的实例类型做了限制
1 | public class LimitClass<T extends List>{ |
<T extends Serializable>
序列化,泛型必须是Serializable
的子类,可传Integer
或String
泛型通配符
1 | A<?> a; |
第14章 lambda表达式与流处理
将lambda表达式用来简化表示匿名函数,也就是没有名字的函数,提高开发效率。
例子:
1 | //函数式接口 |
lamba表达式:
1 | ()->结果表达式 |
例子:
1 | //函数式接口 |
注意:
- lamba表达式不能修改局部变量的值,只能使用
方法的引用
引用静态方法(复制一个已有的函数实现接口,甚至可以不需要这个已有函数内部是如何实现的)
类名::静态方法名
1 | interface StaticMethodInterface{ |
Function接口
Function<T,R>
,T:被操作的类型,可以理解为方法的参数类型;R:操作结果类型,方法的返回类型。
Iterator<T>
只读!
ListIterator<T>
才能修改list的元素
流处理
Stream流只能被消费一次,之后失效
数据过滤
1 | //数据转化为流 |
filter(predicate类)
用lamba表达式不需要管类型,直接放进去
peek(consumer类型)和map()
一个里面不用返回值,一个需要。
collect()
收集重新归类。
第15章 I/O(输入与输出)
graph LR A[I/O]-->输入/输出流 A-->File类 A-->文件输入/输出流 A-->带缓存的输入/输出流 A-->数据输入/输出流
输入/输出流
程序从指向源的输入流中读取源中的数据。
各种数据源通过输入流传递到目的地
源通过数据流传递到各种数据输出目标
InputStream类用来处理字节,不适合处理字符。而Java字符是Unicode编码,双字节,用Reader类处理。但注意Reader类不是InputStream的替换者,只是在处理字符串时简化了编程。
read(byte[] b);返回值是读取到的字节数
File类
File
类是java.io
包中唯一代表磁盘文件本身的类。因为是代表磁盘,操作要用try catch语句
三种构造方式:
1 | File(String pathname) |
1 | import java.io.File; |
File类创建的是一个文件对象!说是在磁盘创建是错误的;除了在内存中的操作,其他都是不保证成功的,
- getName() 文件名称
- length() 文件的长度(以字节为单位)
- isHidden() 判断是否隐藏文件,返回布尔值
文件输入/输出流
FileInputStream与FileOutputStream类
是字节流,读取写入参数得是字节byte,读取汉字容易乱码
- 创建一个FileOutputStream对象时,可以指定不存在的文件,但是不能是已被其他程序打开的文件
- 文件输入流FileInputStream类实现!读取!,用read(byte[] b),从磁盘输入到目的地
- 文件输出流FileOutputStream类实现!写入!,用write(byte[] b),从程序输出到磁盘
案例:
1 | public class FileStreamDemo{ |
FileReader和FileWriter
是字符流,读取写入参数字符串即可
1 | File file=new File("D:\\word.txt");//创建文件对象 |
带缓存的输入/输出流
缓存是I/O的一种性能优化。缓存流增加了内存缓冲区,使得在流上执行skip()
、mark()
和reset()
方法都成为可能。
BufferedReader与BufferedWriter类
分别继承Reader类和Writer类,以行为单位进行输入/输出
读取文件过程:
文件–>InputStream
–>InputStreamReader
–>BufferedReader
–>字符数据
BufferReader类常用的方法:
- read() 读取单个字符
- readLine() 读取一个文本行,返回字符串型。若无返回null
BufferWriter类的方法都返回void:
- write(String s, int off, int len) 写入字符串的一部分
- flush() 刷新流的缓存
- newLine() 写入一个行分隔符
在使用
BufferedWriter
类的Writer()
方法时,数据首先进入缓存区,没有立刻被写入输出流。如果想立即将缓存区中的数据写入输出流,一定要调用flush()
1 | BufferedReader br = new BufferedReader(new FileReader(file));//缓存输入流 |
实例
基本文件操作
1 | public class test2 { |
获取网页源代码
1 | import java.io.*; |
第16章 反射与注释
实现访问、检测和修改描述Java对象本身信息的功能。
getCLass()
是Object类定义的,任何类都可以用,获取类信息
1 |
|
1 | Field[] declaredFields=demClass.getDeclaredFields(); |
1 | //查成员方法 用户输入参数 |
第18章 Swing程序设计
Swing概述
graph LR javax.swing.JLabel-->D[javax.swing.JComponent] Javax.swing.JPanel-->D javax.swing.JDialog-->A[java.awt.Dialog] javax.swing.JFrame-->B[java.awt.Frame] A-->C[java.awt.Window] B-->C D-->E[java.awt.Container] C-->E E-->F[java.awt.Component] F-->java.lang.Object
由Swing包的层次结构和继承关系可知
- Dialog和Frame都在awt.Window里
- 而JDialog在awt.Dialog里,JFrame在awt.Frame里
- JPanel和JLabel在swing.JComponent里
- 它们都在awt.Container里,最顶层是java.lang.Object
Swing常用窗体
public JFrame(String title);
默认不可见窗体,可以标题将窗体转为容器
1
2JFrame jf=new JFrame("登录");
Container container=jf.getContentPane();container.add();container.remove()
添加;删除容器中的组件container
是主容器,组件都在这个范围内JLabel
内容可以用html标签setBounds(距离左边x,距离上边y,宽度,高度)
设置窗体左上角的坐标和大小,对于JFrame
是设置距离屏幕的位置,对于container
里的就是相对灰色的container
位置setLocation(int x,int y);
setSize(int width, int height);
设置窗体宽高setVisibale(boolean b);
是否可见setDefaultCloseOperation(int operation);
设置关闭方式- 默认是
DISPOSE_ON_CLOSE
窗体关闭释放窗体资源,窗体消失但程序不停止 EXIT_ON_CLOSE
窗体关闭,释放窗体资源并关闭程序
- 默认是
Jdialog
对话框
public JDialog(Frame f, Sring title,boolean mode)
设置model
为true
时,打开对话框时,阻塞主窗体不可操作。
JButton
单击事件
1 | class MyJDialog extends JDialog{ |
常用布局管理器
null 绝对布局
硬性指定位置和大小,组件位置通过绝对坐标的方式来指定
- 首先取消布局管理器:
Container.setLayout(null)
- 设置每个组件在容器的位置和大小:
Component.setBounds(int x,int y,int width,int height)
1 | public class AbsolutePosition extends JFrame{ |
FlowLayout 流布局管理器
- 流布局组件从左到右摆放。当组件占据了当前行的所有空间时,溢出的到下一行
- 默认情况,行组件排列方式为居中对齐,可以通过设置更改
FlowLayout类具有以下常用的构造方法
public FlowLayout()
public FlowLayout(int alignment)
public FlowLayout(int alignment,int horizGap,int vertGap)
alignment
参数表示排列方式,可以设置为Flowlayout.LEFT
、FlowLayout.CENTER
或FlowLayout.RIGHT
horizGap
,vertGap
这两个参数以像素为单位指定组件之间的水平间隔和垂直间隔
1 | public class FlowLayoutPosition extends JFrame{ |
BorderLayout 边界布局管理器
Swing创建窗体默认是边界布局管理器
边界布局管理器把容器分为东、南、西、北、中5个区域
当组件添加时,需要使用BorderLayout类中的成员变量指定其区域
BorderLayout.NORTH 北
BorderLayout.SOUTH 南
BorderLayout.EAST 东
BorderLayout.WEST 西
BorderLayout.CENTER 中
———–NORTH———–
WEST—CENTER—-EAST
———–SOUTH———–
add(组件,成员变量)
1 | public class BorderLayoutPosition extends JFrame{ |
GridLayout 网格布局管理器
- 划分为网格,组件可以按行、列进行排序
- 网格个数由行数和列数决定,每个网格大小相同
- 组件从网格左上角开始,从左到右从上到下被添加到网格中
- 每个组件都会填满整个网格
- 改变窗体大小,组件大小也会随之改变
构造方法
public GridLayout(int rows, int columns)
public GridLayout(int rows, int columns, int horizGap, int vertGap)
rows和columns只有一个可以是0,被用于一行或一列排列任意多个组件
1 | public class GridLayoutPosition extends JFrame{ |
常用面板
JPanel 面板
必须在窗体容器中使用,无法脱离窗体显示
1 | Jpanel p1=new JPanel(new GridLayout(1,4,10,10));//初始化面板,使用1行4列的网格布局,组件水平间隔10像素,垂直间隔10像素 |
JScrollPane 滚动面板
1 | Container c=getContentPane(); |
图片路径
1 | Icon con=new ImageIcon("src/注意.png");//使用字符串作为路径,是以项目文件夹为根目录 |
当用new File()
时相对路径是相对于项目的路径,例如JavaSE下面有src,src下面有包,包里有类,当在类中用new File()
相对路径访问src下的文件时应该是
1 | File file=new File("src/[文件名]"); |
事件监听器
ActionEvent动作事件
动作事件监听器
相关定义 | 实现方式 |
---|---|
事件名 | ActionEvent |
事件源 | JButton 、JList 、JTextField 等组件 |
监听接口 | ActionListener |
添加监听方法 | addActionListener() |
删除监听方法 | removeActionListener() |
1 | JButton b1=new JButton("按钮"); |
或者用类调用接口的方法:
1 | public class SimpleEvent extends JFrame{ |
jbAction
实现ActionListner
接口,同时在该内部类中实现actionPerform()
方法,这个方法中定义当用户单击该按钮后实现怎样的功能
KeyEvent键盘事件
KeyEvent
类负责捕获键盘事件,可以通过为组件添加实现了KeyListener
接口的监听器类来处理相应的键盘事件。
KeyListerner
接口3个抽象方法
1 | public interface KeyListener extends EventListener{ |
KeyEvent
类中的常用方法
getKeyChar()
获得与此事件中的键相关联的字符
1 | textField=new JTextField(); |
MouseEvent鼠标事件
所有组件都能发生鼠标事件。添加MouseListener
接口监听,有5个抽象对象
1 | public interface MouseListener extends EventListener{ |
注意单击事件如果按键在移除组件之后才被释放,则不会触发单机事件
MouseEvent类中的常用方法
- getSource() 获得触发此次事件的组件对象,返回值为Object类型
- getButton() 获得按键的int值
- getClickCount() 获得单击按钮的次数
按键的int值:
静态常量 | 常量值 | 代表的键 |
---|---|---|
BUTTON1 | 1 | 鼠标左键 |
BUTTON2 | 2 | 鼠标滚轮 |
BUTTON3 | 3 | 鼠标右键 |
1 | private void mouseOper(MouseEvent e){ |
第二十章 多线程
多种活动同时进行的思想称为并发,而将完成的每一件事情称为线程
CPU在一个时间片中执行某个进程,然后下一个时间片又跳至另一个进程中去执行。由于CPU转换较快,好像同时执行一样
创建线程
- Thread类是java.lang包中的一个类
- 完成线程真正功能的代码放在类的run()方法里
- start()方法会启动线程,线程自动执行run()方法里的代码。
- 如果不调用start()方法,线程永远都不会启动,在主方法没有调用start()前,Thread对象只是实例,不是真正的线程
- 主方法线程由Java虚拟机负责启动
如果start()方法调用一个已经启动的线程,抛出IllegalThreadStateException异常
实现Runnable()接口
当要继承其他非Thread类,通过Runnable接口来实现多线程
1 | public class Threadtest extends Object implements Runnable{ |
实现Runnable()接口的程序会创建一个Thread对象,并将Runnable对象与Thread对象相关联
使用Runnable接口启动新的线程步骤如下:
- 建立Runnable对象
- 使用参数为Runnable对象的构造方法创建Thread实例
- 调用start()方法启动线程
1 | Thread thread=new Thread(new Runnable(){ |
Swing与Thread结合实例
1 | public class SwingAndThread extends JFrame{ |
线程的生命期
- 出生状态就是线程被创建时处于的状态,在用户使用该线程实例调用
start()
方法之前线程都是出生状态。 - 当调用
start()
方法后,线程处于就绪状态(可执行状态) - 当线程得到系统资源进入运行状态。
- 处于运行状态调用
Thread
类中的wait()
方法时,进入等待状态。进入等待状态必须由其他的线程调用notify()
唤醒,自己无法唤醒自己,notifyAll()
方法将所有处于等待状态下的线程唤醒 sleep()
休眠状态,时间到了会自动唤醒,区别于等待状态。- 线程中运行状态下发出输入/输出请求时,该线程将进入阻塞状态。等待输入输出结束时线程进入就绪状态
- 当线程的
run()
方法执行完毕时,线程进入死亡状态。
graph TD 出生-->A[就绪] A-->B[运行] B-->A B-->C[等待] B-->D[休眠] B-->E[阻塞] B-->死亡 C-->A D-->A E-->A
操作线程的方法
线程的加入
join()方法加入到另外一个线程。例如存在一个线程A,现在需要插入B要求线程B先执行完毕,然后再执行线程A,调用join(),类似插入队伍。
当某个线程使用join()加入另外一个线程时,另一个线程会等待该线程执行完毕后再继续执行。
使用方法:在某一个线程A的run函数中使用B.join()插入B线程。
插入到主线程:
1 | public static void main(Stirng[] args){ |
线程的优先级
- 每个线程具有各自的优先级,可以表明在程序中该线程的重要性
- 系统根据优先级决定首先使哪个线程进入运行状态
1 | public class Priority implements Runnable{ |
由输出结果,不一定按优先级,知识作为CPU的参考依据。执行顺序由CPU决定
线程同步
线程安全
线程安全问题来源于两个线程同时存取单一对象的数据
线程同步机制
解决资源共享问题
同步块
synchronized(Object){}
通常将共享资源的操作放置在synchronized
定义的区域内,当其他线程获取这个锁时,就必须等待锁被释放后才可以进入该区域。其中Object
有标志位,0和1,若为0,表示此同步块内存在其他线程,这是当前线程处于就绪状态,直到同步块中的线程执行完同步块代码后,该对象标志位设置为1,当前线程开始执行同步块。
在run()里边添加同步块:
1 | public class SynchronizedTest implements Runnable{ |
如果不加同步块结果会出现负数
线程中执行n++结果不一定正确,因为n++不是原子操作,其中包含三步包括取值,加一,赋值,中间可能会被打断,导致结果不一定准确。可以加入锁解决
1 | synchronized(Object){ |
同步方法
在方法前面用synchronized
关键字修饰方法:
1 | synchronized void f(){} |
同上面的例子实现一样的功能,不过运用同步方法而不是同步块:
1 | public class SynchronizedTest implements Runnable{ |
网络通信
网络程序设计基础
在TCP/IP协议栈中,有两个高级协议,即传输控制协议(Transmission Control Protocol,TCP)与用户数据传输报协议(User Datagram Protocol,UDP)
高级协议 | TCP | UDP |
---|---|---|
特点 | 以固接连线为基础,从一端送至连接的另一端 | 以发送数据包的方式进行,向若干目标发送数据或接受来自若干源的数据 |
数据顺序 | 数据能够送达,且抵达数据的顺序=送出时的顺序 | 不保证抵达的顺序=送出时的顺序 |
类比 | 就像打电话,必须先拨号给对方,等两端确定连接后,互相才能听到对方说法,也知道对方回应的是什么 | 邮递员送信,可以寄出很多信给同一个人,且每封信相对独立。各封信到达的顺序并不重要,收信人接收信件的顺序也不能保证与寄出信件的顺序相同 |
TCP是面向连接的可靠协议,效率低,保证确实送达。UDP是面向无连接的不可靠协议,效率高,不保证数据可靠的传输。
一些防火墙或路由器可能设置不允许UDP数据传输协议
端口
类似营业厅的窗口,提供某些服务
HTTP 80
FTP 21
Tomcat 8080
MySQL 3306
套接字
套接字(Socket)用于将应用程序与端口连接起来。
客户端(应用程序<–>Socket<–>Port<-)-(->Port<–>Socket<–>应用程序)服务器
类似插座一样连接电器与电线
TCP程序
TCP协议进行通信的两个应用程序有主次之分,一个称为服务器程序,另一个称为客户机程序,服务端与客户端的交互过程如下:
- 服务器程序创建一个
SeverSocket
(服务器端套接字)对象,调用accept()
方法等待客户机来连接 - 客户端程序创建一个
Socket
对象,请求与服务器建立连接 - 服务器接受客户机的连接请求,同时创建一个新的
Socket
对象与客户建立连接。随后服务器继续等待新的请求
SeverSocket
可以理解为售后部门的电话;服务器端运行的Socket
可以理解为客服人员;客户端运行的Socket
可以理解为顾客
IntetAddress类
这是一个与ip地址相关的类,可以获取ip地址,主机地址等信息,常用方法:
getByName(String host)
返回InterAddress 获取Host项对应的InterAddress对象getHostAddress()
返回String 获取InterAddress对象所包含的IP地址getHostName(
) String 获取此ip地址的主机名getLocalHost()
InterAddress 返回本地主机的InterAddress对象
1 | public class Address { |
SeverSocket类
服务器套接字
SeverSocket(int port):绑定到接口port的服务器套接字
当服务器向输出流写入信息时,客户端通过相应的输入流就能读取,反之亦然
注意accept()方法会阻塞线程的继续指行,直至接收到客户的呼叫
1 | yu=server.accept(); |
如果没有客户呼叫服务机,那么“连接中”语句不会执行
TCP网络程序设计
单项通信的例子,客户机通过输出流发送数据,服务器通过输入流接收数据:
服务器端:
1 | public class MyServer { |
客户机端:
1 | public class MyClient extends JFrame{ |
UDP程序
UDP通信基本模式:
- 将数据打包(数据包),然后将数据包发往目的地
- 接收别人发来的数据包,然后查看数据包
发送数据包:
- 创建:使用
DatagramSocket()
创建一个数据包套接字。 - 打包:使用
DatagramPacker(byte[] buf, int offset, int length, InetAddress address, int port)
创建要发送的数据包。 - 发送:使用
DatagramSocket()
类的send()
方法发送数据包。
接收数据包:
- 创建:使用
DatagramSocket(int port)
创建数据包套接字,绑定到指定的接口。 - 准备包:使用
DatagramPacket(byte[] buf, int length)
创建字节数组来接收数据包。 - 接收:使用
DatagramPocket
类的receive()
方法接收UDP包。
DatagramPacket类
数据包,构造方法:
DatagramPacket(byte[] buf, int length)
指定包的内存空间和大小DatagramPacket(byte[] buf, int length,InetAddress address,int port)
多指定了数据包的目标地址和端口
发送数据需指定接收方的Socket地址和端口号
DatagramSocket类
- DatagramSocket()
- DatagramSocket(int port)
- DatagramSocket(int port, InetAddress addr) 适用多块网卡有多个IP地址
接收时要指定端口号一般用第二种,发送时不知道用第一种。
UDP网络程序设计
下面创建一个广播数据报程序,原理类似电台广播。广播电台需要在指定的波段和频率上广播信号,接收者也要将收音机调到指定的波段、频率,才可以收听广播内容。
广播主机程序不断向外播出信息:
1 | public class Notification extends Thread{ |
接收广播程序:
1 | public class Receive extends JFrame implements Runnable,ActionListener{ |