第一天:
1windows:
---微软 优点:流畅 缺点:蓝屏+安全性差
linux
---server操作系统
win+r打开运行对话框
notepad记事本 画图mspaint 计算器calc
.exe可执行文件 .class编译后的文件
windiws优化:1、停止不必要的进程
2、停止不必要的服务 --打开服务services.msc
3、调整最佳性能 --设置视觉效果选项卡 调整为最佳性能
4、桌面个性化 --windows经典
5、修改虚拟内存 --50%
栈:先进后出 系统的窗口就是栈结构
进制转换:https://jingyan.baidu.com/article/495ba84109665338b30ede98.html
16进制:0 1 2 3 4 5 6 7 8 9 A B C D E F 以0x开头
0xfe
1、dos命令:dir cd \ d:切换盘符 dir /? 显示帮助 . 当前目录 .. 上级目录 cls 清屏 mkdir创建目录 exit退出 type 显示内容
echo >重定向 覆盖操作 echo >>重定向 追加操作 del删除目录 tree使用树形结构显示文件系统盘 set查看环境变量
2、环境变量
1、java_home 供基于java的软件寻找jdk的执行程序所用
name:java_home
value:c:\download\jdk.1.8.0-65
2、path
name:path
value:%java_home%\bin;......
3、classpath:搜索类的目录顺序
name:classpath
value: %java_home%\bin;%java_home%\lib\tools.jar;
4、重启命令行
5、java -version 查看版本
6、验证是否ok:在任何目录下输入 javac,查看输出结果
运行HelloWorld : javac编译 javac HelloWorld.java
java运行 java HelloWorld
第二天
jre=jdk(java开发工具包)+核心类库
面向对象:继承 封装 多态
进制转换
负数的表现形式:补码(取反+1)
8种基本类型 byte -128~127 1字节=8位
short -32768~32767 2字节
int 4字节
long 8字节
float 4字节
double 8字节
boolean 1字节
char 2字节 \u0000-\uffff
3种引用类型:数组 class interface
特殊字符 \t制表 \r换行 \n回车
s+=5与s=s+5的区别
答:s+=5是进行自动类型转换的,
比如说我们在编写Java程序的时候,有时候会发现定义一个short型的变量s,
short s = 4;
然后s = s+5报错,而s+=5却没有问题,这是怎么回事呢。
因为5是整型数,占4个字节,而short占2个字节,当s+5的时候,s为short型会转为int型与5运算,可是结果却要赋给精度低的short型,会丢失精度。所以会报错,编译不通过
但是s+=5这一运算不同,就是一次运算,只有一次赋值运算,会自动转换,编译通过。
instance判断对象是否是指定的类型,后面跟的是引用类型
它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。举个例子: String s = "I AM an Object!"; boolean isObject = s instanceof Object;
我们声明了一个String对象引用,指向一个String对象,然后用instancof来测试它所指向的对象是否是Object类的一个实例,显然,这是真的,所以返回true,也就是isObject的值为True。
&逻辑与与&&短路与的区别 :& 左边无论真假,右边都进行运算 && 如果左边为真,右边参与运算,如果左边为假,则右边不参与运算
false&true都判断 false&&true
^问:
异或:相同二进制进行运算 相同为0,不同为1
为什么 & |没有短路?
-128存储形式?
计算机中0是整数还是负数:负数
成绩float 用switch写出 优良中差 与不及格
打印直角三角形 空心三角形 乘法表
//空心三角形
public static void print6(int size){
for(int i=1;i<=size;i++){
if(i==size){//第一行等于最后一行
for(int j=0;j<2*size-1;j++){
System.out.print("*");//打印*
}
}else{
for(int j=1;j<=size-i;j++){//打印空格
System.out.print(" ");
}
for(int k=1;k<=2*i-1;k++){//第一行到最后一行
if(k==1||k==2*i-1){ //第一行或最后一行
System.out.print("*");
}else{
System.out.print(" ");//中间打印空格
}
}
System.out.println();
}
}
}
//菱形
public static void print5(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n - i; j++) {
System.out.print(" ");
}
for (int k = 1; k <= 2 * i - 1; k++) {
System.out.print("*");
}
System.out.println();
}
for (int i = 1; i < n; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(" ");
}
for (int k = 1; k <= (n - i) * 2 - 1; k++) {
System.out.print("*");
}
System.out.println();
}
}
左移<<和右移>>
三目运算符:System.out.println(b<40?"小于":"不小于");
比较三个数的大小,可嵌套
int x=5; int y=6;int z=7;
System.out.println( x>y?(x>z?x:z):(y>z?y:z));
switch 语句可选择的类型 byte short int char
在jdk1.7版本以前,参数类型只能是short、byte、int、char可正常运行。而例如String,Long、Integer、double、float等则会报错。
而jdk1.7版本以后,参数类型除了之前可使用的外,String、Integer类、 Character类、枚举类型都可以正常运行。而Long、double、float依旧会报错。
while与for的区别:for循环定义的变量在for循环结束时就在内存中释放,while循环使用的变量在循环结束后还可以继续使用
第三天
方法:具有特定功能的一段独立小程序
方法的格式
调用方法
前n项和
public static void He(int n){
int sum =0;
for(int i=0;i<=n;i++){
sum=sum+i;
}
}
动态乘法表
pubclic static void table(int row){
for(int i=1;i<=row;i++){
for(int j=1;j<=i;j++){
System.out.print(j+"*"+i+"="+(i*j)+"\t");
}
System.out.println(\r\n);
}
}
计算阶乘
public static int fabric(int n){
if(n<=0){
return -1;
}
int res=1;
for(int i=1;i<=n;i++){
res=res*i;
}
return res;
}
}
递归 rescursive
public static int fac(int n){
if(n=1){
return 1;
}
return n * fac(n-1);
}
}
数组:同一种数据类型的集合。
数组的定义 类型[] 变量名=new 类型[数值] 数组的长度固定 int [] a=new int[10]; int[] a={1,2,3}
length()是属性,不是方法
定义数组,并直接初始化 int[] arr=new int[] {1,2,3};
问:提取数组元素最大值
public static int getMax(int[] arr){
if(arr==null||arr.length==0){
return -1;
}
int max=arr[0];
for(int i=1;i<arr.length;i++){
max=max>arr[i]?max:arr[i]
}
}
栈:方法在栈中,方法的调用链条 存储局部变量,数据使用完,所占空间会自动释放
堆:对象和数组在堆中;是jvm最大的内存空间
冒泡排序:每一次选出当前元素中最大的数放在末尾
public static void maoPao(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {//外层循环控制排序趟数
for (int j = 0; j < arr.length - 1 - i; j++) {//内层循环控制每一趟排序多少次
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int ii : arr) {
System.out.println(ii);
}
}
选择排序:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,
public static void selectSort(int [] arr){
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
}
public static void print(int [] arr){
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]+" ");
}
}
}
折半查找(二分法)
public class Demo1 {
/**
* * A:案例演示
* 数组高级二分查找代码
* B:注意事项
* 如果数组无序,就不能使用二分查找。
* 因为如果你排序了,但是你排序的时候已经改变了我最原始的元素索引。
*/
public static void main(String[] args) {
int[] arr = {11,22,33,44,55,66,77};
System.out.println(getIndex(arr, 22));
System.out.println(getIndex(arr, 66));
System.out.println(getIndex(arr, 88));
}
/*
* 二分查找
* 1,返回值类型,int
* 2,参数列表int[] arr,int value
*/
public static int getIndex(int[] arr, int value) {
int min = 0;
int max = arr.length - 1;
int mid = (min + max) / 2;
while(arr[mid] != value) { //当中间值不等于要找的值,就开始循环查找
if(arr[mid] < value) { //当中间值小于了要找的值
min = mid + 1; //最小的索引改变
}else if (arr[mid] > value){ //当中间值大于了要找的值
max = mid - 1; //最大的索引改变
}
mid = (min + max) / 2; //无论最大还是最小改变,中间索引都会随之改变
if(min > max) { //如果最小索引大于了最大索引,就没有查找的可能性了
return -1; //返回-1
}
}
return mid;
}
输出一个整数的二进制
public static int byteScope(byte b){
return b&xxff;
}
public static void putIntBinaryString(int n){
for(int i=31;i>= 0;i--){
System.out.print((n>>i)&0x1);
}
System.out.println();
}
二维数组 :九宫格
第三天
1、把一个数组的元素放进另一个数组里,可截断
public static void arrayCopy(int [] arr1,int [] arr2){
if(arr1.length>arr2.length){
for(int i=0;i<arr2.length;i++){
arr2[i]=arr1[i];
}
}else{
for(int i=0;i<arr2.length;i++){
arr2[i]=arr1[i%(arr1.length)];
}
}
for(int i=0;i<arr2.length;i++){
System.out.print(arr2[i]+" ");
}
}
2、矩阵转置(二维数组)
public static void rever(int[][] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < i; j++) {
int temp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = temp;
}
}
}
public static void out(int[][] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
3、面向对象与面向过程
满汉全席的例子 对象:先找负责人 过程:自己全做一遍
面向过程强调功能行为 面向对象将功能封装进对象,强调具备了功能的对象
4、类和对象的关系
对象:是实实在在的个体 类:对现实事务的软件抽象
5、成员变量有默认初始化值 局部变量需手动初始化
day04
一、java -x 查看java非标准输出帮助
java -Xmx100m 设置jvm的堆空间最大值
-Xms100m 设置jvm的堆空间初始值
二、匿名对象 new Person().run();
作为参数进行传递 run
三、封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式
1、子类会继承父类的所有东西,而修饰符只是影响属性或者方法对外是否可见。
2、子类不能继承父类的私有属性,但是如果子类中公有的方法影响到了父类私有属性,那么私有属性是能够被子类使用的
四、构造函数
1、函数名和类名形同
2、无返回值
3、可以重载
4、如果类没有定义构造函数,jvm分配一个空构造
5、创建对象
五、构造代码块 {}
从上到下按序执行
六、对象的创建过程
1、静态代码块:在类加载期间执行,且只执行一次
2、静态成员不可以访问非静态
3、静态成员变量通过类来访问
七、this和super
指向对象自身的引用,用于区分成员变量和方法的形参。
this()访问当前类的构造函数,且必须 在第一行,为了构造函数的重用
super()访问父类的构造函数
八:static
随着类加载而加载
优先于对象存在
被所有对象所共享
可以直接被类名调用
静态方法不可以写this,super
问:百钱买百鸡
公鸡:5/只 母鸡:3/只 小鸡1/3只 100元买100只
public class Buy {
//公鸡5yuan一只,母鸡3元一只,小鸡3只一元钱,100元买100只
public static void main(String[] args) {
for (int i = 0; i < 100 / 5; i++) {
for(int j=0;j<100/3;j++){
for(int k=0;k<100;k=k+3){
int count=i+j+k;
int money=i*5+j*3+(k/3);
if(money==100&&count==100){
System.out.println("公鸡:"+i+"母鸡:"+j+"小鸡"+k);
}
}
}
}
}
}
九、方法的重写与重载
重写(Override)存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法,子类的返回值类型要等于或者小于父类的返回值;
重载(Overload)存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同。应该注意的是,返回值不同,其它都相同不算是重载
方法覆盖:1、静态覆盖静态。非静态覆盖非静态
2、非私有方法,才能重写
3、子类的访问权限要大于父类的方法访问权限
十、子类的实例化过程:
子类中所有的构造函数默认都会访问父类中空参数的构造函数,因为每一个构造函数的第一行都有一条默认的语句super();
十一、final
类 方法 变量
十二、内部类:
1、定义在类内部的类成为内部类
2、内部类可以在类成员位置上
3、内部类还可以在方法内定义
4、内部类访问局部变量时,不能局部变量进行重新赋值。java8不要求必须给局部变量使用final修饰
day04
一、抽象类
抽象方法:没有函数体的方法,必须使用abstract修饰,abstract void cry();必须在抽象类中
抽象类不能实例化
抽象类:1、可以有构造函数
2、由子类来实例化
二、非法修饰符组合: private+abstract fianl+abstract
三、接口interface :最低标准 usb例子
成员变量:public static final
成员函数:public void white();
特点:所有方法都是抽象的,用来多实现,功能扩展
面向接口编程:降低耦合度,可多重继承
四、多态:同一种事物表现出的多种形态
三个条件: 必须要有继承
必须要重写
父类引用指向子类对象
ClassCastException:类转换异常
类中方法可以覆盖,成员变量(资产)不能覆盖
五、匿名内部类:简化代码量,将类的声明,方法的实现,对象的创建一气呵成
public class 匿名内部类 {
public static void main(String[] args) {
tuHao t = new tuHao(new Bfm() {
@Override
public void white() {
System.out.println("white....");
}
});
}
}
interface Bfm {
void white();
}
class tuHao {
public tuHao(Bfm bfm) {
bfm.white();
}
}
六、适配器模式
接口适配器:有时我们写的一个接口中有多个抽象方法,当我们写该接口的实现类时,必须实现该接口的所有方法,
这明显有时比较浪费,因为并不是所有的方法都是我们需要的,有时只需要某一些,此处为了解决这个问题
我们引入了接口的适配器模式,借助于一个抽象类,该抽象类实现了该接口,
实现了所有的方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们写一个类,继承该抽象类,
重写我们需要的方法就行。
public class Adapter {
public static void main(String[] args) {
Button b1=new Button();
//匿名内部类对象
b1.addListener(new MouseAdapter() {
@Override
public void onClick() {
System.out.println("单机");
}
@Override
public void onDbClick() {
System.out.println("双击");
}
});
b1.click();
b1.onDbClick();
}
}
//按钮
class Button{
private MouseListener listener;
public void addListener(MouseListener listener){
this.listener=listener;
}
public void click(){
listener.onClick();
}
public void onDbClick(){
listener.onDbClick();
}
}
//鼠标监听器
interface MouseListener{
public void onClick();
public void onDbClick();
public void rightClick();
public void leftClick();
}
//鼠标适配器
abstract class MouseAdapter implements MouseListener{
public void rightClick(){ //可空实现
}
public void leftClick(){
}
}
day05
异常
一、
throw抛出异常对象的指令 throws在方法中修饰抛出异常的关键字
try-catch-finally
finally只有一种情况不会执行,就是sysyem.exit();
可以有多个catch语句,catch的顺序需要注意,子类异常需要先行catch,否则代码不可达,编译无法通过
方法重写时,不能声明抛出新的异常类型,只能是原有的异常体系。
二、java -cp classes -d xxx.java //-cp指定编译程序时需要搜索的类路径顺序
java -d classes xxx.java //-d
指定存放classes文件的位置,同时生成对应的目录树
三、包、权限
jar cvf xxx.jar -C foo/ . //将foo目录下的所有文件进行归档,生成xxx.jar
四、进程:1、运行时的应用程序
2、进程之间的内存不是共享(独占)
3、进程间通信使用套接字 socket
线程:1、进程内并发执行的代码段
2、线程之间共享内存
3、创建灵活响应的桌面程序
4、每个运行的线程对应一个stack
5、应用程序至少有一个线程(主线程)
五、创建线程的方式
栈溢出:死递归
1、Thread.yield() 让当前线程让出cpu抢占权,具有谦让之意,顺时的动作
2、Thread.sleep()让当前线程休眠指定毫秒数
3、Thred.join() 当前线程等待指定的线程结束后才能继续运行
4、Thread.setDaemon(true); 守护线程 为其他线程提供服务的线程
若进程中剩余线程都是守护线程的话,则进程终止了
线程间通信,产生共享资源的问题:加锁,防止并发访问。由并行变为串行
例子:在火车上上厕所,抢到之后马上上锁,出来后,其他线程继续抢;
synchronized
取票问题:
public class Ticket {
public static void main(String[] args) {
Saler s1 = new Saler("s1");
Saler s2 = new Saler("s2");
s1.start();
s2.start();
}
}
class Saler extends Thread {
static int tickets = 100;
static Object lock = new Object();
private String name;
public Saler(String name) {
this.name = name;
}
public void run() {
while (true) {
int t = getTickets();
if (t == -1) {
return;
} else {
System.out.println(name + ":" + t);
}
}
}
//取票
public int getTickets() {
synchronized (lock) {
int t = tickets;
tickets = tickets - 1;
return t < 1 ? -1 : t;
}
}
}
六、同步方法public synchronized void save(){}与同步代码块synchronized(object){}的区别?
同步代码块执行期间,线程始终持有对象的监控权,其他线程只能等待
七、同步静态方法 ,使用类作为同步标记
public staitc synchronized xxx(...){
}
八、生产者和消费者
public class ThreadDemo {
public static void main(String[] args) {
Pool pool = new Pool();
Productor p1 = new Productor("生產者", pool);
Productor p2 = new Productor("生產者", pool);
Customer c1 = new Customer("消費者", pool);
p1.start();
p2.start();
c1.start();
}
}
//生产者
class Productor extends Thread {
static int i = 0;
private String name;
private Pool pool;
public Productor(String name, Pool pool) {
this.name = name;
this.pool = pool;
}
public void run() {
while (true) {
pool.add(i++);
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("生产了" + i + "");
}
}
}
//消费者
class Customer extends Thread {
private String name;
private Pool pool;
public Customer(String name, Pool pool) {
this.name = name;
this.pool = pool;
}
public void run() {
while (true) {
int i = pool.remove();
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("消费了" + i);
}
}
}
//生产 删除方法类
class Pool {
private List<Integer> list = new ArrayList<Integer>();
//容量最大值
private int Max = 100;//防止栈溢出,到达100等待
//添加元素
public void add(int n) {
synchronized (this) {
try {
while (list.size() >= Max) {
this.wait(1);
}
list.add(n);
System.out.println("size =="+list.size());
this.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//刪除元素
public int remove() {
synchronized (this) {
try {
while (list.size() == 0) {
this.wait(1);
}
int i = list.remove(0);
this.notify();
return i;
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
}
}
需要注意的是:java.lang.IllegalMonitorStateException
wait和notify方法的调用必须处在对象的锁中,调用这些方法时首先需要获得该对象的锁
消费者被唤醒后是从wait()方法后面执行,而不是重新从同步块开始
九、wait()和sleep()的区别?
sleep() :释放cpu执行权,不释放锁
wait():让当前线程进入锁旗标的等待队列,释放cpu执行权,释放锁
暂定当前正在执行的线程,并释放资源锁,让其他线程可以有机会运行(程序停顿在这一行).
notify()
十、解决死锁的问题
notifyAll()通知所有线程可以抢占cpu和锁旗标监控权
wait(1000);等待固定的時間點
day06
equals() 与 == 的区别
对于基本类型,== 判断两个值是否相等(内存地址),基本类型没有 equals() 方法。
对于引用类型,== 判断两个实例是否引用同一个对象,而 equals() 判断引用的对象(对象内容)是否等价。需重写。
一、Runnable接口
1、接口
2、public void runn(){};
3、使用Runnable对象创建线程(有3中创建方式)
new Thread(Runnable r).start();
4、供现有类实现线程功能
5、静态同步方法是使用class作为锁;
6、非静态同步方法是使用this(当前对象)作为锁;
public class Test {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}).start();
}
}
二、CAS:compare and set
避免同步带来的效率降低
三、线程安全问题
同步方法,同步代码块,静态同步代码块
四、线程的六种状态:
1.new 新建
2.runnable 可运行
3.blocked等待监视器的锁定权 synchronized(this) 阻塞
4.waiting 一个线程等待另一个线程特定的操作 wait();
5.timed waiting 限时等待 wait(参数);
6.terminated 死亡
7.sleep休眠
五、String
1、一旦初始化不可被改变
2、创建String的区别:
String s1="abc";//产生一个对象
String s2=new String("abc");//产生二个对象
3、String类的部分方法
例子:
public class ziFu {
public static void main(String[] args) {
String s1 = "abc defga";
String s2 = "gzzz";
System.out.println(s1.charAt(1));// 返回指定索引处的 char 值。 b
System.out.println(s1.contains(s2));//当且仅当此字符串包含 char 值的指定序列时,才返回 true。
System.out.println(s1.length());// 返回此字符串的长度。
System.out.println(s1.toCharArray()); //将此字符串转换为一个新的字符数组。
System.out.println(s1.indexOf("a"));//返回指定字符在此字符串中第一次出现处的索引
System.out.println(s1.endsWith(s2));// 测试此字符串是否以指定的后缀结束。
System.out.println(s1.getBytes());//将字符串转换成字节数组
System.out.println(s1.replace(s1,s2));//用s2替换s1
System.out.println(s1.toUpperCase());//变为大写 toLowerCase()小写
String [] s3=s1.split(" ");// 根据给定的正则表达式的匹配来拆分此字符串。
System.out.println(s3);
System.out.println(s1.substring(2));//截取
System.out.println(s1.substring(1,7));//截取左闭右开区间 bcdefg
}
}
4、debug
5、编码表:
ASCII:7位表示 GBK UniCode:国际标准码 2个字节 UTF-8:最多使用3个byte表示字符
小组合作开发先调字符集:Utf-8码
字符在内存中存储的都是unicode码
day07
作业:字符串反转
1、StringBuffer 的reverse方法
2、利用栈
3、递归
一、StringBuffer
1、字符串缓冲区
2、线程安全的
二、StringBuilder
1、字符串构建器
2、线程不安全
三、包装类wrapper
boolean —> Boolean
char —> Character
byte—> Byte
short—> Short
long—> Long
int —> Integer
float—> Float
double—> Double
四、建造器模式
五、自动拆箱与自动装箱
1、自动装箱:将基本类型自动装换成包装类对象
2、自动拆箱:将包装类对象自动装换成基本类型
Integer a=new Integer(12); //自动装箱 Integer a=12;
Integer b=new Integer(13);
a+b=a.intValue()+b.intValue();
六、基本类型与包装类的区别(int 与Integer的区别)
1、包装类是对象,拥有方法和字段;基本类型不是
2、包装类是引用传递,基本类型是值传递。
3、存储位置不同,基本类型在栈中,包装类型在堆中
4、声明方式不同,基本类型不需要new,包装类需要new在堆内存中,通过对象的引用来调用。
5、包装类可以声明为null,基本类型需初始化 Inteager a=null;
七、泛型
八、集合
数组:元素类型相同、长度固定、地址连续、下标访问以0为基址
集合:只能存放对象元素类型可以不同、长度可变
collection的两个接口:list接口:有序可重复 set接口:无序不重复 (TreeSet特殊有序)
ArrayList:数组 查找快 存储满
list add(..)
list.remove(index);
list.get(index);
list.clear();
LinkedList:链表 通过手拉手实现对象引用,存储快,查询慢
九、重写equals()
public voolean equals(Object obj){
//1、obj==null
if(obj==null){
return false;
}
//2、是否是同一对象
if(this==obj){
return true;
}
//3、判断obj是否是person实例
if(obj instanceof Person){
Person p0=(Pserson)obj;
if(this.name.equals(p0.name)&&this.age==p0.age){
return true;
}
}
return fasle;
}
}
十、迭代器
Iterator it=i.terator();
while(it.hasNext()){
System.out.println(it.next());
}
day08
一个中文占几个字节?(不同的编码格式下)
一、Map
1、map接口是单独的接口,没有继承任何接口,与之前的jdk版本不同
2、key-value对,称为Entry
3、map.size()是entry的数量
4、put放入,get提取
5、HashMap.hash()方法意义
6、Node<k,v>
class Node<k,v>{
final int hash; //新hash
final k key; //key不能修改
v value, //value
Node <k,v>next; //
}
7、元素重复的判断标准
(p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))
8、(p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))
a. new Hash不同,对象不同
b. new Hash相同。对象是同一对象,则对象相同
c. new Hash相同,对象不是同一对象,再判断equals方法,则对象相同性判定和equals一致
5、迭代entrySet keySet
//迭代Map entrySet
Set<Map.Entry<String, String>> entries = map.entrySet();
Iterator<Map.Entry<String, String>> iterator = entries.iterator();
while(iterator.hasNext()){
Map.Entry<String,String> entry = iterator.next();
String key=entry.getKey();
String value=entry.getValue();
System.out.println(key+"==="+value);
}
//增加for
Set<Map.Entry<Integer, String>> entries = map.entrySet(); //crtl+alt+v
for(Map.Entry<Integer,String> entry:entries){
Integer key=entry.getKey();
String value=entry.getValue();
System.out.println(key+"==="+value);
}
//迭代key keySet
Set<String> set = map.keySet();
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
String key=iterator.next();
String value=map.get(key);
System.out.println(key+"=="+value);
}
//增加for
Set<Integer> keys = map.keySet();
for(Integer key:keys){
System.out.println(key+"==="+map.get(key));
}
//迭代value
Collection<String> values = map.values();
Iterator<String> iterator = values.iterator();
while(iterator.hasNext()){
String value = iterator.next();
System.out.println(value);
}
二、
问:
hashMap中的hash算法的实现原理,为什么?
1、为什么移位?高16位向右移动16位,由高低16位做异或运算:目的是哈希值跟特征值相关
2、为什么异或?相同为0,不同为1 使对象更加分散
hashMap扩容?bucket
三、唯一性
HashSet:通过hashMap实现的
TreeSet:通过compareTo或者compare方法,元素以二叉树的形式存放
四、集合的嵌套
public class Demo {
public static void main(String[] args) {
//班级人数5
List<String> names = null;
//年级:10个班级的集合
List<List<String>> grades = null;
// 学校:6个年级的集合
List<List<List<String>>> school = new ArrayList<List<List<String>>>();
for (int i = 1; i <= 6; i++) {
//创建每个年级,是班级的集合
grades = new ArrayList<List<String>>();
school.add(grades);
//处理每个年级的班级集合
for (int j = 1; j <= 10; j++) {
names = new ArrayList<String>();
grades.add(names);
for (int k = 1; k <= 5; k++) {
names.add("tom--" + i + "-" + j + "-" + k);
}
}
}
outName(school);
}
//迭代输出
public static void outName(List<List<List<String>>> allNames) {
Iterator<List<List<String>>> it = allNames.iterator();
//每个年级
while (it.hasNext()) {
List<List<String>> grade = it.next();
//班级
Iterator<List<String>> classes = grade.iterator();
while (classes.hasNext()) {
List<String> names = classes.next();
Iterator<String> nameIt = names.iterator();
while (nameIt.hasNext()) {
System.out.println(nameIt.next());
}
}
}
}
}
day09
一、Map与Collection在集合中并列存在
Map存储元素用put,Collection使用add方法
Map没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素
Map集合中key要保持唯一性
二、HashMap与HashTable与TreeMap
三、集合工具类
Collection的max,min,synchronizedList,sort
Arrays的sort,asList,binarySearch
四、可变参数
public void add(String a,String...str) jdk1.5之后必须是方法的最后一个参数
五、数组的拷贝
public class test1 {
public static void main(String[] args) {
int a1[]={1,2,3,4,5};
int a2[]=new int[10];
//public static native void arraycopy(Object src,int srcPos, Object dest, int destPos,int length);
// 原数组,原数组的开始位置,目标数组,目标数组的的开始位置,拷贝的个数
System.arraycopy(a1,1,a2,3,3);
System.out.println(Arrays.toString(a1)); //[1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)); //[0, 0, 0, 2, 3, 4, 0, 0, 0, 0]
}
}
day10
一、IO流
流的类型
字符流:操作文本 Reader Writer
字节流:二进制文件 InputStream OutputStream 可操作媒体文件。字符串
流向
输入:读操作
输出:写操作
二、java.io.FileWriter
1、new FileWriter(String path);
2、write(String str);写入字符数据到流中
3、flush() 清理流
4、close()关闭 ,隐藏了flush()操作
5、流在close之后,不能再写入数据
可重复关闭,不会出现问题
读文件要比写文件复杂
public class Test {
public static void main(String[] args) {
try {
FileReader reader = new FileReader("d:/hello.txt");
char[] buffer = new char[3];
int length = -1;
while ((length = reader.read(buffer)) != -1) {
System.out.println(new String(buffer, 0, length));
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
定义文件路径时,可以用"/"或者"\\"
作业:1、实现文件的复制
public class Test {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("d:/hello.txt");
FileOutputStream fos = new FileOutputStream("H:/hello.txt");
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
fos.flush();
}
fis.close();
fos.close();
System.out.println("over");
} catch (Exception e) {
e.printStackTrace();
}
}
}
2、文件的刪除
public class Test2 {
public static void main(String[] args) {
File dir=new File("d://liu");
deleteFile(dir);
}
private static void deleteFile(File dir) {
File[] files = dir.listFiles();//1,获取该文件夹下的所有的文件和文件夹
for (File file : files) {//2,遍历数组
if (file.isFile()) {//3,判断是文件直接删除
file.delete();
} else {
deleteFile(file); //4,如果是文件夹,递归调用
}
}
dir.delete();//5,循环结束后,把空文件夹删掉
System.out.println("删除完毕");
}
3、使用FileWriter,将1-100万写入到文本中
4、hashSet和hashMap的关系
5、文件切割与合成
三、装饰模式
四、缓冲区字符流
1、BufferReader:这个类就是一个包装类,它可以包装字符流,将字符流放入缓存里,先把字符读到缓存里,到缓存满了或者你flush的时候,再读入内存,就是为了提供读的效率而设计的。
2、BufferWriter
BufferedInputStream和BufferedOutputStream这两个类分别是FilterInputStream和FilterOutputStream的子类,作为装饰器子类,使用它们可以防止每次读取/发送数据时进行实际的写操作,代表着使用缓冲区。
我们有必要知道不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!
同时正因为它们实现了缓冲功能,所以要注意在使用BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。否则可能无法写出数据。与之相似还BufferedReader和BufferedWriter两个类。
BufferedInputStream和BufferedOutputStream类就是实现了缓冲功能的输入流/输出流。使用带缓冲的输入输出流,效率更高,速度更快。
五、函数的回调
六、单元测试
@Test 要求:不能带参不能有返回值不能是静态方法
FileInputStream
支持skip()方法,skip向后跳的时候不能是文件头地址,可以超过文件末尾地址
FileOutputStream
不支持skip
RandomAccessFile
随机访问文件,定位到文件的任意位置
学习笔记 ,不断更新。
猜你喜欢
转载自blog.csdn.net/qq_36523209/article/details/85339473
今日推荐
周排行