一、集合
集合框架
java.util.Collection接口:该接口是所有集合的顶级接口,规定了所有集合都应当具备的 功能方法
*
Collection下面又分为不同的集合类型,常见的有两个:
- java.util.Set接口:不可重复集,常用实现类java.util.HashSet
- java.util.list:可重复集,并且有序,常用实现类:java.util.ArrayList和LinkList
这里的重复是元素是否可以重复,而重复元素的判定标准是元素自身equals比较是否为true
1.1 集合的基本方法
添加(boolean add(E e))、统计个数(int size())、判断是否为空(boolean isEmpty())、清空指令(.clear())
/*
* boolean add(E e)
* 向当前集合中添加给定的元素,返回值为true时表示该元素成功添加的集合中
*/
Collection c = new ArrayList();
//Collection c = new HashSet();
c.add("one");
c.add("two");
c.add("tree");
c.add("foue");
c.add("one");//List集合可以存放,Set集合就不行了
System.out.println(c);
/*
* int size()
* 返回当前集合的元素个数
*/
int size = c.size();//真实反映集合中的元素个数,而数组的lenth是能放多少
System.out.println("size:"+size);
/*
* boolean isEmpty()
* 判断当前集合是否为空集(集合不含任何元素,即size为0时
*/
Boolean isEmpty = c.isEmpty();
System.out.println("集合是否为空集:"+isEmpty);
c.clear();
System.out.println(c);
System.out.println("size:"+c.size());
System.out.println("是否为空集:"+c.isEmpty());
1.2 集合与equals方法相关操作
判断是否包含指定元素:boolean contains(E e)
删除指定元素:boolean remove(E e)
Collection c =new ArrayList();
c.add(new Point(1,2));
c.add(new Point(3,4));
c.add(new Point(5,6));
c.add(new Point(7,8));
System.out.println(c);
Point p = new Point(1,2);
/*
* boolean contains(E e)
* 判断当前集合是否包含给定元素,判断依据是给定元素与集合现有元素
* 是否存在equals比较为true的情况,存在则认为包含
*/
boolean contains = c.contains(p);
System.out.println(contains);
/*
* boolean remove(E e)
* 删除给定元素,删除的也是与给定元素equals比较为true的元素。
* 对于List集合而言重复元素只会删除一次。
*/
c.remove(p);
System.out.println(c);
1.2 集合只能储存引用变量
集合只能存放引用类型元素,并且保存的也是元素的引用(地址)
Point p = new Point(1,2);
Collection c = new ArrayList();
c.add(p);
System.out.println("p:"+p);//(1,2)
System.out.println("c:"+c);//[(1,2)]
p.setX(2);
System.out.println("p:"+p);//(2,2)
System.out.println("c:"+c);//[(2,2)]
二、聊天室练习
2.1 服务端
package socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
/**
* 聊天室的客服端
* @author 毛
*
*/
public class Server {
/*
* 服务端使用的是ServerSocket
* 它有两个作用:
* 1:向系统申请端口。
* 2:接收请求该端口的所有客户端的连接。
*/
private ServerSocket server;
/*
* 内部类可以访问外部类的属性,因此所有ClientHandler都可以访问到外部类
* Server属性,所有这里定义一个数组保存所有ClientHandler对应客户端的
* 输出流就可以做到共享了,以便每个客户端发消息过来对应的ClientHandler都可以
* 通过遍历数组拿到对应客户端的输出流广播消息
*/
private PrintWriter []allout = { };
/**
* 服务端构造方法,用来初始化服务端
*/
public Server() {
try {
/*
* 实例化的同时向系统申请服务端口,客户端Socket就是通过这个
* 端口与服务端建立连接的。如果该端口被系统其他程序占用了则
* 会抛出异常:
* java.net.BindException:address already in use: JVM_bind
*
* 遇到该错误时解决办法:
* 1:首先检查是否自己开启过两次服务端,因为第一次启动已经占用了
* 该端口,如果再启动一遍时还申请该端口就会提示被占用了。
* 2:如果没有启动过两次,那说明系统其他程序占用该端口了,需要更
* 换一个可用的。
*/
System.out.println("正在启动服务端...");
server = new ServerSocket(8088);
System.out.println("服务端启动完毕!");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 服务端开始工作的方法
*/
public void start() {
try {
/*
* ServerSocket提供的方法:
* Socket accept()
* 该方法是一个阻塞方法,调用该方法后程序"卡住",此时开始等待
* 客户端的连接,一旦客户端实例化Socket并连接服务端这边申请的
* 端口(8088)时,accept方法会立即返回一个Socket实例,此时等于
* 和客户端建立了连接。服务端通过返回的这个Socket就可以与客户端
* 进行交互了。
* 多次调用accept方法可以接收多个客户端的连接。
*/
while(true){
System.out.println("等待客户端连接...");
Socket socket = server.accept();
System.out.println("一个客户端连接了!");
//启动一个线程处理客户端交互
ClientHandler handler = new ClientHandler(socket);
Thread t = new Thread(handler);
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
/**
* 该线程任务用来与客户端交互
*/
private class ClientHandler implements Runnable{
private Socket socket;
private String host;//记录客户端的IP地址信息
public ClientHandler(Socket socket){
this.socket = socket;
//通过socket获取远程计算机地址信息(对于服务器而言远端就是客户端)
host=socket.getInetAddress().getHostAddress();
}
public void run(){
PrintWriter pw = null;
try{
/*
* Socket提供的方法:
* InputStream getInputStream();
* 通过该方法获取的输入流读取的字节是远端计算机发送过来的字节
*/
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in,"UTF-8");
BufferedReader br = new BufferedReader(isr);
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
BufferedWriter bw = new BufferedWriter(osw);
pw = new PrintWriter(bw,true);
/*
* 将输出流存入共享数组allout中
*/
synchronized(allout){
//1 将allout数组扩容
allout = Arrays.copyOf(allout, allout.length+1);
//2 将输出流存入数组最后一个位置
allout[allout.length-1] = pw;
}
System.out.println(host+"上线了,当前在线人数:"+allout.length);
String message = "";
while((message = br.readLine())!=null) {
System.out.println(host+"说:"+message);
//回复给所有客户端
synchronized(allout){
for(int i=0;i<allout.length;i++){
allout[i].println(host+"say:"+message);
}
}
}
}catch(Exception e){
}finally{
//处理客户端断开连接操作s
synchronized(allout){
//将对应当前客户端的输出流从数组allout中删除
for(int i=0;i<allout.length;i++){
if(allout[i]==pw){
allout[i]=allout[allout.length-1];
allout = Arrays.copyOf(allout, allout.length-1);
break;
}
}
}
System.out.println(host+"下线了,当前在线人数为:"+allout.length);
try{
/*
* socket的close方法调用后会与远程计算机断开此时
* 通过socket获取的输入流与输出流也被close了、
*/
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
2.2客户端
package socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 聊天室的客户端
* @author 毛
*
*/
public class Client {
/*
* java.net.Socket 套接字
* Socket封装了TCP协议的通讯细节,使用它就可以与服务端建立网络连接了,
* 并且进行通讯。这里的通讯是以两条流的读写完成与服务端的数据交换的。
*/
private Socket socket;
/**
* 客户端构造方法,用于初始化客户端
*/
public Client() {
try {
/*
* 实例化Socket时需要传入两个参数:
* 1:服务端的地址信息(IP)
* 2:服务端打开的端口
*
* 我们可以通过IP找到网络上的服务端计算机,通过其打开的端口
* 可以连接到服务端应用程序。
*/
System.out.println("正在连接服务端...");
socket = new Socket("localhost",8088);
System.out.println("已连接服务端!");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 客户端开始工作的方法
*/
public void start() {
try {
//先启动用于读取服务端发送消息的线程
ServerHandler handler = new ServerHandler();
Thread t = new Thread(handler);
t.start();
/*
* Socket提供的方法:
* OutputStream getOutputStream()
* 通过socket的该方法获取的输出流写出的字节会通过网络发送给
* 远端计算机。
*/
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw,true);
Scanner scanner = new Scanner(System.in);
while(true) {
String message = scanner.nextLine();
pw.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
/**
* 该线程负责循环读取服务端发送过来的消息
* @author 毛
*
*/
private class ServerHandler implements Runnable{
public void run(){
try{
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in,"utf-8");
BufferedReader br = new BufferedReader(isr);
String message;
while((message = br.readLine())!=null){
//读取客服端发送回来的一行字符串
System.out.println(message);
}
}catch(Exception e){
}
}
}
}
练习
/*5*/
Collection c51 = new ArrayList();
Collection c52 = new HashSet();
c51.add("123");
c52.add("456");
c52.add("456");
System.out.println(c51+","+c52);
int size51=c51.size();
int size52 = c52.size();
System.out.println(size51);
System.out.println(size52);
boolean isempty5 = c51.isEmpty();
System.out.println(isempty5);
isempty5 = c52.isEmpty();
System.out.println(isempty5);
c52.clear();
System.out.println(c52+","+c52.size()+","+c52.isEmpty());
/*4*/
Collection c41 = new ArrayList();
Collection c42 = new HashSet();
c41.add("123");
c42.add("123");
c42.add("456");
System.out.println(c42+","+c41);
int size4 = c41.size();
System.out.println(size4);
System.out.println(c42.size());
System.out.println(c41.isEmpty()+","+c42.isEmpty());
c41.clear();
System.out.println(c41+","+c41.size()+","+c41.isEmpty());
/*3*/
Collection c31=new ArrayList();
Collection c32= new HashSet();
c31.add("asd");
c32.add("zxc");
c31.add("asd");
c32.add("zxc");
System.out.println(c31+","+c32);
System.out.println("c31:"+c31.size()+","+c31.isEmpty()+":c32:"+c32.size()+","+c32.isEmpty());
c41.clear();
System.out.println("c31:"+c31.size()+","+c31.isEmpty()+":c32:"+c32.size()+","+c32.isEmpty());
/*2*/
Collection c21 = new ArrayList();
Collection c22 = new HashSet();
c21.add("123");
c21.add("123");
c22.add("345");
c22.add("345");
System.out.println(c21+","+c22);
System.out.println("c21:"+c21.size()+","+c21.isEmpty()+":c22:"+c22.size()+","+c22.isEmpty());
c22.clear();
System.out.println("c21:"+c21.size()+","+c21.isEmpty()+":c22:"+c22.size()+","+c22.isEmpty());
/*1*/
Collection c11 = new ArrayList();
Collection c12 = new HashSet();
c11.add("123");
c11.add("123");
c12.add("345");
c12.add("345");
System.out.println(c11+","+c12);
System.out.println("c11:"+c11.size()+","+c11.isEmpty()+":c12:"+c12.size()+","+c12.isEmpty());
c12.clear();
System.out.println("c11:"+c11.size()+","+c11.isEmpty()+":c12:"+c12.size()+","+c12.isEmpty());
/*5*/
Collection c5 =new ArrayList();
c5.add(new Point(1,2));
c5.add(new Point(3,4));
c.add(new Point(5,6));
c.add(new Point(7,8));
System.out.println(c);
Point p5 = new Point(1,2);
boolean contains5 = c5.contains(p5);
System.out.println(contains5);
c.remove(p5);
System.out.println(c5);
/*4*/
Collection c4 = new ArrayList();
c4.add(new Point(1,2));
c4.add(new Point(3,4));
c4.add(new Point(4,5));
System.out.println(c4);
Point p4 = new Point(1,2);
boolean ct4 = c4.contains(p4);
System.out.println(ct4);
c4.remove(p4);
System.out.println(c4);
/*3*/
Collection c3 = new ArrayList();
c3.add(new Point(1,2));
c3.add(new Point(2,3));
c3.add(new Point(3,4));
System.out.println(c3);
Point p3 = new Point(2,3);
boolean ct3 = c3.contains(p3);
System.out.println(ct3);
c3.remove(p3);
System.out.println(c3);
/*2*/
Collection c2 = new ArrayList();
c2.add(new Point(1,2));
c2.add(new Point(2,3));
c2.add(new Point(3,4));
System.out.println(c2);
Point p2 = new Point(3,4);
boolean ct2 = c2.contains(p2);
System.out.println(ct2);
c2.remove(p2);
System.out.println(c2);
/*1*/
Collection c1 = new ArrayList();
c1.add(new Point(1,2));
c1.add(new Point(2,3));
c1.add(new Point(3,4));
System.out.println(c2);
Point p1 = new Point(1,2);
boolean ct1 = c1.contains(p1);
System.out.println(ct1);
c1.remove(p1);
System.out.println(c1);
/*5*/
Point p5 = new Point(1,5);
Collection c5 = new ArrayList();
c5.add(p5);
System.out.println("p5:"+p5);//1,5
System.out.println("c5:"+c5);//1,5
p5.setX(5);
System.out.println("p5:"+p5);//5,5
System.out.println("c5:"+c5);//5,5
/*4*/
Point p4 = new Point(2,4);
Collection c4 = new ArrayList();
c4.add(p4);
System.out.println("p4:"+p4);//2,4
System.out.println("c4:"+c4);//2,4
p4.setX(4);
System.out.println("p4:"+p4);//4,4
System.out.println("c4:"+c4);//4,4
/*3*/
Collection c3 = new ArrayList();
Point p3 =new Point(3,3);
c3.add(p3);
System.out.println("p3:"+p3);//3,3
System.out.println("c3:"+c3);//3,3
p3.setY(33);
System.out.println("p3:"+p3);//3,33
System.out.println("c3:"+c3);//3,33
/*2*/
Collection c2 = new ArrayList();
Point p2 = new Point(4,2);
c2.add(p2);
System.out.println("p2:"+p2);//4,2
System.out.println("c2:"+c2);//4,2
p2.setX(44);
System.out.println("p2:"+p2);//44,2
System.out.println("c2:"+c2);//44,2
/*1*/
Point p1 = new Point(5,1);
Collection c1 = new ArrayList();
c1.add(p1);
System.out.println("p1:"+p1);//5,1
System.out.println("c1:"+c1);//5,1
p1.setX(55);
System.out.println("p1:"+p1);//55,1
System.out.println("c1:"+c1);//55,1