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"); } }