java2
格式化快捷键:Ctrl+alt+l
灯泡快捷键:alt+enter
数组得事先定义好长度
泛型:
<E>就像相当于函数的参数:

上面2曾是接口,第三层是实现类:

sout快速输出System...


ArrayList:

retainAll是取交集。
ArrayList:

是否包含:



结果:


返回第一个对象的index:

返回最后出现的:


HashMap:



原理:
使用了哈希表存储(Entry数组)

即邻接表


key和vaue是整合一体的:

TreeMap能排序:
key也可以是对象,自定义比较方法:




HashSet:

TreeSet:
按序输出(Tree)
自定义类时也要实现comparable接口



迭代器遍历:
iterator:
遍历list,set类似:

快捷键:Ctrl + shift + o:快速导入
遍历map:

存储表格:



第二种方法:


IO:
"abc".getBytes:[a的ASCII,b的ASCII,c的ASCII]
File类:
new File('c:/a.txt')创建文件对象:
获得当前项目目录,在当前目录下新建文件:


绝对路径:



递归输出某个目录下的所有文件 :

分隔符separator:

创建对象:
获得大小多少k


绝对,相对路径 :


文件方法:


创建和删除文件:
createNewFile:创建的是文件不是文件夹,若文件已经存在,则不会动它并返回false,否则返回true并创建文件

创建目录:
mkdirs:


list:得到某个文件夹下一级目录的所有名称,存入字符串数组中
listFiles:得到某个文件夹下一级目录的所有文件,存入文件数组中

递归打印某文件夹下的所有东西:

统计文件夹大小:

字符集:
编码:


编码解码:
length:字节数

字节流:字节为单位;字符流:字符(2个字节)为单位
节点流:直接接到数据源;处理流:套在节点流外面

不用new File也行,直接把文件路径名放入放入到流的参数里面也行,它会自动new File的。
read:读字节:
一个英文是一个字节,一个汉字是2个字节
read()一下是对单个字节进行一下编码,返回编码的结果,所以不能读汉字:
FileInputStream:



一段一段地读:
read(flush):按照最大范围(flush数组长度)去读字节,返回具体读到了多少字节,每个字节的编码放到flush数组中,最后new String()把它们解码并拼接起来。

FileOutputStream:
输出流.write(字节编码): 把解码字节并写到输出流指向的文件中
true表示继续追加,false表示覆盖:

字符流:FileReader:(图片文件不行)
输入流.read():读到一个字符
FileWriter:(图片文件不行)
可以:输出流.write(字符数组) ,输出流.write(字符串) ,输出流.append(字符串)
flush:将流里面的数据冲到硬盘上,清空流



处理流:
BufferedInputStream:套在InputSteam外面,具有缓冲区的功能:
read()返回编码:
BufferedReader:套在FileReader外面,用它主要因为它有readLine方法。
newLine:添加一个换行符
readLine:读一行

转换流:
字节流和字符流之间的转化:
OutputStreamWriter:将OutputStream转为Writer,之后就能直接以字符串作为参数了:
参数true表示追加

System.in的一端指向控制台:

数据流:
ByteArrayOutputStream:先在内存建立一个字节数组,然后引出一个指向字节数组的输出流
DataOutputStream:可以输出指定类型的数据(double...),把它套在字节流上,不仅提高性能还能调用专门的方法:
available():当前字节数组有几个字节
读字节数组的时候是以队列的方式先读最先写入的:

Print流:
主要用于输出操作不会抛出异常,且System.ou属于PrintStream:

setOut:之前输出到命令行,现在改到ps

将文件内容输出到控制台:
System.out是PrintSream对象,该流的一端指向控制台

将InputStreamReader的一端指向控制台的输入,再套一个BufferedReader
每次拿到一行控制台数据便输出到文件中
类似日志记录


Object流:
要对一个对象进行IO,那么对象所属的类需要实现Serializable接口(不需要重写),告诉编译器先将对象转成字节流再进行IO
存一个对象再读出来

transient:在进行序列化时不考虑k变量,不存k

externalizable:自定义控制实现序列化过程
多线程:
创建线程:

1.

2.

方法:
sleep:
Thread.sleep():使得当前线程进入睡眠状态
interrupt停止线程后,该线程进入catch。。。。。

join:
在A线程里调用了b.join,执行到此处时就得停下来等,等b线程执行完毕后自己继续执行
super是调用父类的方法给name属性赋值

yield:
自己暂时不执行让别的线程执行一下,但可能没有效果:

priority:
默认5
越大则执行概率越大:

synchronized:通过操纵锁对象实现方法的互斥使用
用synchronized看住一个公共对象obj(锁对象),当一个线程进入方法块中,就拿到了锁对象obj,另一个线程得等线程释放锁对象才能再次拿到obj,然后进入方法体。
要想实现同步就得把同步代码块放到synchronized里面
同步代码块:
下图中三个线程的start调用的是同一个对象run的run方法:
如果不给Thread起名字,则默认有名字且可以通过getName来拿到:Thread-0,Thread-1...


同步方法:
锁对象是调用方法的对象:

或者:

由于synchronized修饰,在m1执行时,m2 不能执行,反之。但普通方法能执行

wait,sleep,notify:
wait后就释放了锁对象。
wait后必须被唤醒才能执行
notify:唤醒一个在wait的线程
notifyAll:唤醒所有线程
网络编程:
双向链路的一端:socket

建立服务器监听端口8888
accept等待客户端连接,若没有连则一直等


UDP:
dp是将客户端发过来的数据存到包
随后建立udp监听5678
receive等待消息过来

客户端在自己的9999端口发送包:

GUI:
flowLayout是panel的默认布局管理器
borderLayout是frame的默认
Frame:


坐标:

Panel可以容纳component
setBounds(int x,int y,int width,int height);x,y是坐标
frame相对于窗口,而panel相对于frame


布局管理器:
FlowLayout:
从左向右排列,一行排满到下一行继续排列。
这种布局是响应式,默认是居中


可以设置左对齐

设置组件间的水平间距和垂直间距:

BorderLayout:



GridLayout:
第二个参数4不考虑,列数通过指定的行数和布局中的组件总数来确定。

pack():设置正好包住那几个butn,没有多余的空间


总结:

事件:
按钮点击事件:

一个监听器对象监听2个按钮:
setActionCommand:作用就是另外设置一个字符串来判断你究竟选择的是哪一个组件

TextField:
在文本框输入内容后打印到控制台:
按enter键会触发事件:

设置文本框的显示字符是*:

实现:

TextField(10)是设置长度为10


或者使用成员内部类:






Graphics:
重写paint方法,当一些事件发生时(如重写显示窗口)自动调用paint,通过Graphics g来画图:
fillOval(50,50,30,30):画实心的椭圆,50,50是位置,30,30是长宽
PaintFrame extends Frame后,构造方法里自动调用父类构造函数生成一个Frame了,此时只需在里面设置setVisible(true)就能显示出来


实现:

repaint内部先update再paint

匿名类:


匿名类实现按钮关闭:
此处new WindowAdapter:new父类对象(){重写方法}

实现:


KeyEvent:
敲向上键才会有打印输出:

仿制QQ:
目录结构:
第一个包是后台,第二个是工具类,第三个是客户端,第四个是公共类


新建登录类界面
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) :点击关闭按钮时退出程序
布局:
整体是BorderLayout,北部是一个Jlabel,里面是图片;南面是Jpanel,里面3个button;
中部是一个选项卡JTabbedPane,它里面加了三个Jpanel,第一个panel是GridLayout

新建列表类界面
布局:使用卡片布局,整体显示的是一个卡片,当点击陌生人按钮时,整体切换到另一个卡片。
卡片模型:
装入2个卡片,第一个卡片用面板1呈现(代号为1),第二个。。。
this.setLayout(new CardLayout());
this.add(面板1,"1");
this.add(面板2,"2");
默认显示面板1

show(卡片容器a,"asd"):假定a设定为卡片布局(卡片容器,或卡片集合),展示a中的名为asd的卡片。
如果是frame.setLayout的话,则参数一是frame的内容面板:frame.getContentPane()
在我的好友卡片1中:
在面板1中:
JLabel(“asd”, new ImageIcon("images/a.jpg"),JLabel.LEFT) :此标签内容:a.jpg asd ,而且内容左对齐
JScrollPane friScrollContent = new JScrollPane(friJpContent); 在ScrollPane里面装东西直接写到()里面,不要add

卡片2中:
点击卡片1的按钮陌生人的显示新卡片2:


当鼠标移到某人上时字体变成红色,移开则变成黑色。
QqFriendList:
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class QqFriendList extends JFrame implements ActionListener,MouseListener{
CardLayout c;
// 卡片1:展示我的好友
JPanel card1;
// 顶部
JButton friMy;
// 中间联系人
JScrollPane friScrollContent;
JPanel friJpContent ;
int friNum = 50; // 联系人个数
// 底部
JPanel friBottom;
JButton friStranger;
JButton friBlock;
// 卡片2:展示陌生人
JPanel card2;
// 顶部
JPanel strHead;
JButton strStranger;
JButton strMy;
// 中间联系人
JScrollPane strScrollContent;
JPanel strJpContent ;
int strNum = 20; // 联系人个数
// 底部
JButton strBlock;
QqFriendList(String friends){
super(friends);
// 卡片1
// 顶部
friMy = new JButton("我的好友");
card1 = new JPanel(new BorderLayout());
card1.add(friMy, BorderLayout.NORTH);
// 中间内容
friJpContent = new JPanel(new GridLayout(friNum,1,4,4)); // 最后2个参数是行间距和列间距
JLabel[] friPeople = new JLabel[friNum];
for(int i=0;i<friNum ; i++){
// 每个JLabel有个text属性,此处设置为i+1
friPeople[i] = new JLabel(i+1+"",new ImageIcon("images/mm.jpg"),JLabel.LEFT);
friPeople[i].addMouseListener(this);
friJpContent.add(friPeople[i]);
}
friScrollContent = new JScrollPane(friJpContent);
card1.add(friScrollContent,BorderLayout.CENTER);
// 底部按钮
friStranger = new JButton("陌生人");
friStranger.addActionListener(this);
friBlock = new JButton("黑名单");
friBottom = new JPanel(new GridLayout(2,1));
friBottom.add(friStranger);
friBottom.add(friBlock);
card1.add(friBottom,BorderLayout.SOUTH);
c = new CardLayout();
this.setLayout(c);
this.add(card1,"card1");
// 卡片2
// 顶部
strMy = new JButton("我的好友");
strMy.addActionListener(this);
strStranger = new JButton("陌生人");
card2 = new JPanel(new BorderLayout());
strHead = new JPanel(new GridLayout(2,1));
strHead.add(strMy);
strHead.add(strStranger);
card2.add(strHead,BorderLayout.NORTH);
// 中间内容
strJpContent = new JPanel(new GridLayout(strNum,1,4,4)); // 最后2个参数是行间距和列间距
JLabel[] strPeople = new JLabel[strNum];
for(int i=0;i<strNum ; i++){
strPeople[i] = new JLabel(i+1+"",new ImageIcon("images/mm.jpg"),JLabel.LEFT);
strPeople[i].addMouseListener(this);
strJpContent.add(strPeople[i]);
}
strScrollContent = new JScrollPane(strJpContent);
card2.add(strScrollContent,BorderLayout.CENTER);
// 底部按钮
strBlock = new JButton("黑名单");
card2.add(strBlock, BorderLayout.SOUTH);
this.add(card2,"card2");
setSize(140,400);
setLocation(300,300);
setVisible(true);
}
public static void main(String[] args) {
new QqFriendList("好友列表");
}
@Override
public void actionPerformed(ActionEvent e) {
// this.getContentPane()拿到Frame的getContentPane
// 如果点击了卡片1中的“陌生人”按钮,则进入卡片2
// 如果点击了卡片2中的“我的好友”按钮,则进入卡片1
if(e.getSource()==friStranger){
c.show(this.getContentPane(),"card2");
}else{
c.show(this.getContentPane(),"card1");
}
}
@Override
public void mouseClicked(MouseEvent e) {
JLabel target = (JLabel) e.getSource();
System.out.println(target.getText());
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
// 鼠标移上触发
@Override
public void mouseEntered(MouseEvent e) {
JLabel lb = (JLabel)e.getSource();
lb.setForeground(Color.RED);
}
// 鼠标移开触发
@Override
public void mouseExited(MouseEvent e) {
JLabel lb = (JLabel)e.getSource();
lb.setForeground(Color.BLACK);
}
}
QqClientLogin:
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
public class QqClientLogin extends JFrame{
// 北部组件
JLabel jlNorth ;
// 中部组件
JTabbedPane jt;
JPanel jp1;
JPanel jp2;
JPanel jp3;
JLabel jlNumber;
JLabel jlPassword;
JLabel jlForget;
JLabel jlProtect;
JButton jp1_clear;
JTextField tfUsername;
JPasswordField tfPassword;
JCheckBox jcLogin;
JCheckBox jcRemember;
// 南部组件
JPanel jpSouth;
JButton jpSouth_jb1;
JButton jpSouth_jb2;
JButton jpSouth_jb3;
QqClientLogin(String title){
super(title);
// 北部组件
jlNorth = new JLabel(new ImageIcon("images/tou.gif"));
add(jlNorth, BorderLayout.NORTH);
// 中部组件
jlNumber = new JLabel("QQ号码",JLabel.CENTER);
jlPassword = new JLabel("QQ密码",JLabel.CENTER);
jlForget = new JLabel("忘记密码",JLabel.CENTER);
jlForget.setForeground(Color.BLUE);
jlProtect = new JLabel("申请密码保护",JLabel.CENTER);
jp1_clear = new JButton(new ImageIcon("images/clear.gif"));
tfUsername = new JTextField();
tfPassword = new JPasswordField();
jcLogin = new JCheckBox("隐身登录");
jcRemember = new JCheckBox("记住密码");
jp1 = new JPanel(new GridLayout(3,3));
jp1.add(jlNumber);
jp1.add(tfUsername);
jp1.add(jp1_clear);
jp1.add(jlPassword);
jp1.add(tfPassword);
jp1.add(jlForget);
jp1.add(jcLogin);
jp1.add(jcRemember);
jp1.add(jlProtect);
jp2 = new JPanel();
jp3 = new JPanel();
jt = new JTabbedPane();
jt.add("QQ号码",jp1);
jt.add("手机号码",jp2);
jt.add("电子邮箱",jp3);
add(jt,BorderLayout.CENTER);
// 南部组件
jpSouth = new JPanel();
jpSouth_jb1 = new JButton(new ImageIcon("images/denglu.gif"));
jpSouth_jb2 = new JButton(new ImageIcon("images/quxiao.gif"));
jpSouth_jb3 = new JButton(new ImageIcon("images/xiangdao.gif"));
jpSouth.add(jpSouth_jb1);
jpSouth.add(jpSouth_jb2);
jpSouth.add(jpSouth_jb3);
add(jpSouth,BorderLayout.SOUTH);
setLocation(300,300);
setSize(350,240);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new QqClientLogin("QQ");
}
}

浙公网安备 33010602011771号