记录生活中的点点滴滴

0%

一、NIO的使用中两个重要的要素:

 缓冲区(Buffer)、通道(Channel)

 缓冲区(Buffer):存储数据的。 —->byte[] buffer = new byte[1024]

 通道(Channel):代表着数据源与目标节点之间的连接,负责缓冲区的传输。 —>IO流

 二者的交互:Java NIO 中的 Buffer 主要用于与 NIO 通道(Channel)进行交互, 数据是从通道读入缓冲 区, 从缓冲区写入通道中的。

二、缓冲区(Buffer)的结构 (除boolean之外)

 java.nio.Buffer抽象类

  |—-ByteBuffer

  |—-CharBuffer

  |—-ShortBuffer

  |—-IntBuffer

  |—-LongBuffer

  |—-FloatBuffer

  |—-DoubleBuffer

XxxBuffer底层使用xxx[]进行存储。

三、如何实例化缓冲区?调用缓冲区类XxxBuffer的静态方法:allocate(int capacity)

  举例:ByteBuffer byteBuffer = ByteBuffer.allocate(10);byte[] hb = new byte[10];

  类似:ArrayList list = new ArrayList(10);//Object[] eleData = new Object[10];

 说明:方法的形参,决定了底层创建的数组的长度

四、Buffer中的常用属性:

  capacity:容量,决定了底层数组的长度,表明了最大存储数据的容量

  limit:限制,默认情况下,limit等于capacity.在读数据模式下,limit<=capacity.表明最大可以读取数据的量position:位置,表明了当前读取或写入数据的位置

  mark:标记。默认值为-1.

  关系式:mark <= position <= limit <= capacity

  类比:项目三中TeamService类中的属性:

   private final int MAX_MEMBER = 5;//相当于capacity

   private Programmer[] team = new Programmer[MAX_MEMBER];//Buffer底层封装的数组

   private int total;//相当于limit

   index:读取、写入数组指定为的索引:position

五、Buffer中的常用方法:

  1)最基本的两个方法:put(Xxx xxx) / get()

  2)其他方法:见ppt中的表格即可。

六、针对于ByteBuffer来讲,可以创建非直接缓冲区:allocate(int capacity)

​ 直接缓冲区:allocateDirect(int capacity) / FileChannel 的 map()

了解非直接缓冲区 与 直接缓冲区的区别

byteBuffer.put(“hello”.getBytes());//写入长度为5的字节数.每put一个字节,position就+1

byteBuffer.flip();//切换为读数据模式。将limit设置为position,position归零

byteBuffer.rewind();//重置position

byteBuffer.clear();//清空.将position归零,limit设置为capacity.数据并未删除。

byteBuffer.get(dst,0,2);//从数组角标0开始,写入两个字节的数组

if(byteBuffer.hasRemaining()){

//判断是否还有元素没有读取到。

​ System.out.println(byteBuffer.remaining());//还有几个没有读取到。

}System.out.println();

equals 判断字符串内容

Math.random [0, 1)

想获取【a,b】的数 ( int )(Math.random()*(b-a+1)+a)

分支结构2:switch-case

switch 语句的结束标志: } ,break

default 可选,位置比较灵活

switch中的表达式所代表的数据类型6种,只能是如下byte,short,char,int,枚举,String(jdk7.0新增)

case 后只能是常量或者是常量表达式

多个case可以共用一组语句,在最后一个case上写要执行的语句就好了,这里的最后一个case并不是}附近的一个,而是你要停止的一个

凡是swith-case实现的结构,都可以转成if-else实现,反之不成立

字符串方法:

获取字符:charAt()

循环结构4要素:

初始化条件

循环条件 —>布尔类型

循环体

迭代条件

当循环条件返回false,结束循环

for和while 可以相互转换

循环结构的结束方式:

1.循环条件返回false时

2.在循环体中,判断某个条件满足时,执行break (不确定循环次数时)

​ while(true) / for(;;)

嵌套循环:

一个循环结构a,作为另一个循环结构b的循环体实现

内层循环:循环结构a

外层循环:循环结构b

技巧:

1.外层循环控制行数

内层循环控制列数

2.

内层循环循环次数为m次,外层循环循环次数为n次,则一共循环m*n次

一、要想实现网络通信,需要解决两个问题:

  1.如何准确的定位互联网上的一台或多台主机

  2.如何实现可靠而高效的数据传输

二、网络通信的两个要素:

  1.使用IP地址,定位网络中的主机

  2.遵循相关的网络通信协议

三、针对要素一:

  1.IP:一个ip地址,对应着网络中的一台主机。 “192.168.20.16” “127.0.0.1”–本地回路地址

    使用InetAddress类来代表IP,一个InetAddress类的对象,就代表着一个具体的ip地址。

  2.如何实例化InetAddress:

    ①getByName(String hostName)

    ②getLocalHost()

  3.域名: www.baidu.com www.jd.com www.mi.com www.vip.com

       www.facebook.com

​ localhost对应着127.0.0.1

  4.InetAddress类的常用方法:getHostName() / getHostAddress()

  5.端口号标识正在计算机上运行的进程(程序)

    注意:不同的进程有不同的端口号

    常见的端口号: http:80 tomcat : 8080 mysql:3306 oracle:1521等

jdk 8 之前 日期+时间 API的使用

java.util.Date类

  |—-java.sql.Date类

1.java.util.Date类:

  如何实例化:两个构造器

  常用方法:toString() / getTime();

2.java.sql.Date类:与数据表中的Date类型的变量对应。

构造器一:获取系统当前时间对应的Date对象

Date date = new Date();

getTime():返回当前日期对应的毫秒数:当前时间与1970-1-1 00:00:00直接的毫秒数

构造器二:获取毫秒数所对应的Date对象

Date date1 = new Date(1502768492941L);

SQl:

java.sql.Date date2 = new java.sql.Date(1502768492941L);

SimpleDateFormat

使用默认构造器:SimpleDateFormat sdf = new SimpleDateFormat();

格式化:String format(Date date):

 Date date = new Date();

 String dateStr = sdf.format(date);

解析: Date parse(String dateStr)

 Date date1 = sdf.parse(“17-8-15 下午2:18”);

 System.out.println(date1);

java.text.SimpleDateFormat类

 1.SimpleDateFormat的作用:

   格式化:日期—>文本

   解析:格式化的逆过程,文本 —>日期

 2.SimpleDateFormat实例化

  使用带参数的构造器

   SimpleDateFormat sdf1 = new SimpleDateFormat(“EEE, d MMM yyyy HH:mm:ss Z”);    

   SimpleDateFormat sdf1 = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”);

  格式化:

   String dateStr1 = sdf1.format(date);

   System.out.println(dateStr1);//2017-08-15 02:24:40

  解析:

   Date date2 = sdf1.parse(“2017-08-15 02:24:40”);

   System.out.println(date2);

java.util.Calendar(日历)类的使用

  1.实例化Calendar calendar = Calendar.getInstance();

  2.get()

​  int day = calendar.get(Calendar.DAY_OF_MONTH);

​  System.out.println(day);

  3.set()

   calendar.set(Calendar.DAY_OF_MONTH, 20); 

   day = calendar.get(Calendar.DAY_OF_MONTH);

   System.out.println(day);

  4.add()

   calendar.add(Calendar.DAY_OF_MONTH, -2);

   day = calendar.get(Calendar.DAY_OF_MONTH);

   System.out.println(day);

日历 —>日期

  Date date = calendar.getTime();

  System.out.println(date);

使用指定的Date对象,来设置calendar

  Date date1 = new Date();

  calendar.setTime(date1);

  day = calendar.get(Calendar.DAY_OF_MONTH);

  System.out.println(day);

LocalDate / LocalTime / LocalDateTime —–重要//理解为对Calendar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//实例化
//now()
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();

System.out.println(localDate);
System.out.println(localTime);
System.out.println(localDateTime);

//of()
LocalDate localDate2 = LocalDate.of(2017,8,15);
System.out.println(localDate2);
LocalDateTime localDateTime2 = LocalDateTime.of(2017, 8, 15, 11, 11,23); System.out.println(localDateTime2);
System.out.println();
//getXxx():
System.out.println(localDateTime.getDayOfYear());
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getDayOfWeek());
System.out.println(localDateTime.getMonth());
System.out.println(localDateTime.getMonthValue());
System.out.println(localDateTime.getHour());
System.out.println(localDateTime.getMinute());
//withXxx():体现了不可变性
LocalDateTime localDateTime3=localDateTime.withDayOfMonth(20); System.out.println(localDateTime);
System.out.println(localDateTime3);
LocalDateTime localDateTime4=localDateTime.withHour(12); System.out.println(localDateTime4);
//plus()//minus()
LocalDateTime localDateTime5 =localDateTime.plusDays(3); System.out.println(localDateTime5);
LocalDateTime localDateTime6 =localDateTime.minusMinutes(20);
System.out.println(localDateTime6);
boolean isBefore =localDateTime.isBefore(localDateTime6);
System.out.println(isBefore);//false
boolean isAfter =localDateTime.isAfter(localDateTime6); System.out.println(isAfter);//true
//isLeapYear():
System.out.println(localDate.isLeapYear());
LocalDate localDate3 =localDate.minusYears(1);
System.out.println(localDate3.isLeapYear());

Optional类使用的测试

 Optional:是一个封装了具体类型数据的容器。

 其中,具体的类型:通过Optional的泛型体现。

 具体类型的数据:通过Optional内部的T value体现

返回一个没有封装任何数据的Optional对象

  Optional op = Optional.empty();0

  Optional op1 = Optional.ofNullable(“beijing”);

isPresent():判断内部的数据是否存在

get():返回Optional对象内部封装的数据

of(T t):当t为null时,报异常。建议不用此方法

orElse(T t):如果调用对象包含值,返回该值,否则返回t

Integer类作为int的包装类,能存储的最大整型值为2^31−1,

BigInteger类的数值范围较Integer类、Long类的数值范围要大得多,可以支持任意精度的整数。

在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。

BigDecimal类支持任何精度的定点数。

素数判断:

1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Scanner;
public class f1{
public static void main(String[] args){
for(int i=2;i<=100000;i++){
boolean isFlag = true;
for(int j=2;j<i;j++){
if(i%j==0){
isFlag=false;
}
}
if(isFlag){
System.out.println(i);
}
}

}
}

这种方式浪费内存,外循环 boolean = true 相当于每次重新定义一个变量

2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Scanner;
public class f1{
public static void main(String[] args){
boolean isFlag = true;
for(int i=2;i<=100000;i++){
for(int j=2;j<i;j++){
if(i%j==0){
isFlag=false;
}
}
if(isFlag){
System.out.println(i);
}
isFlag = true;
}
}
}

这种方式多写一行代码

3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class f1{
public static void main(String[] args){
long start = System.currentTimeMillis();
int PrimeNumberCount = 0;
for(int i=2;i<=100000;i++){
boolean isFlag = true; //标识
//优化2:针对于质素数的优化
for(int j=2;j<=Math.sqrt(i);j++){
if(i%j==0){
isFlag=false;
//优化1:主要针对于非质数
break;// 结束包裹break关键字最近的一层
}
}
if(isFlag){
PrimeNumberCount++;
}
}
System.out.println(PrimeNumberCount);
long end = System.currentTimeMillis();
System.out.println("时间:"+(end-start));
}
}

currentTimeMillis() 获取系统当前时间对应的毫秒数

break 结束包裹break关键字最近的一层

break 和 continue

适用范围: 在循环中,表示:

break: switch-case 或者 循环结构 结束当前循环

continue: 循环结构 结束当次循环

相同点:

关键字后面不能有输出语句,编译不通过

附加:带标签的break和continue的使用

一:面型对象的三条主线

  1.j a v a类及类的成员:属性、方法、构造器;代码块、内部快

  2.面型对象的三个特性:封装、继承、多态、(抽象性)

  3.其他关键字的使用:this、super、abstract 、interface 、import 、package、static 、final等

二:面向过程与面向对象的理解

例子1:人打开门

面向过程:

人打开了门

面向对象:

人{

​ 打开(门){

​ 门.开开();

}

}

门{

​ 开开.( ){

}

}

例子2:人把大象img装进冰箱

面向过程:人打开冰箱,抬起大象,加进冰箱,关闭冰箱门

面向过程:

人{

​ 打开(冰箱){

​ 冰箱.开开();

}

​ 抬起(大象){

​ 大象.进入(冰箱);

}

关闭(冰箱){

​ 冰箱.闭合();

​ }

}

大象{

​ 进入(冰箱){}

}

冰箱{

​ 开开(){}

​ 闭合(){}

}

三:面向对象当中的两个核心概念:类与对象

  类:一类事物的描述,抽象的,概念上的定义。

  对象:类的具体的体现,实实在在存在的个体

 

  Scanner 类

  Scanner s = new Scanner(S y s t e m .i n); s:对象 s. n e x t();

  面向对象程序设计重点是类的设计

四:类的主要成员:属性,方法

   属性 = 成员变量 = filed = 域 

  方法 = 成员方法 = 成员函数 = method

currentTimeMillis

  • 获取系统当前时间对应的毫秒数
  • 获取1970.1.1 00:00:00 到 当前时间的毫秒数

数组(array):多个相同数据类型变量的组合在一起,便于管理

  • 一维数组的声明和初始化

    数组的声明 int[] x,int x[];

    int[] score;

    String[] names;

  • 初始化

    静态初始化:数组的初始化和元素赋值是同时进行的

    score = new int[]{60,70,80,90,100}

    动态初始化:数组的初始化和元素赋值是分开进行的

    names = new String[4];

    name[0] = “凉生”

总结:不管是静态初始化,还是动态初始化,一旦初始化完成,其长度就是确定的!

错误的初始化:

int[] = new int[4]{60,70,80,90,100}

int[3] = new int[]{60,70,80,90,100}

int[] arr = {1,2,3} 简化写法: 类型推断

如何获取数组的长度:数组的属性:length

数组元素的遍历:

1
2
3
4
int[] score = new int[]{1,2,3,4,5};
for(int i=0;i<score.length;i++){
System.out.println(score[i]);
}

一维数组的使用:

不同类型数组的默认初始化问题:

基本数据类型:

  整型数组:byte short int long 的默认数组元素的初始化值都是0

  浮点型数组:float double 的默认数组元素的初始化值都是0.0

  字符型数组:char 的默认数组元素的初始化值都是’\u0000’ 或者 0(不要理解为:’ 0 ‘)

        从形式上来说是空格

  布尔类型:boolean 的默认数组元素的初始化值:false

引用数据类型:

  数组,接口,类的默认数组元素的初始化值为:null

总结:数组本身属于引用数据类型

   数组元素,可以是基本数据类型也可以是引用数据类型。

一维数组的内存解析(难点)

二维数组:一维数组的元素,恰好又是一维数组

二位数组的声明方式:int[ ] [ ]y,int[ ] y[ ],int y[ ] [ ]

二维数组的初始化:

  静态初始化:

   String[][] [ ] [ ] arr1 = new int[3] [2];

  动态初始化1:

   int[ ] [ ] arr2 = new int[3] [2];

  动态初始化2:

   int[] [] arr3 = new int[3] [ ];

   arr3[0] = new int[3];

   arr3[1] = new int[2];

   arr3[2] = new int[4];

通过下角标的方式进行数组元素的调用

arr2[1] [0] = 1;

数组的属性:length

System.out.println(arr.length) //3

System.out.println(arr[0].length) //2

System.out.println(arr[1].length) //2

System.out.println(arr[2].length) //2

二维数组的使用:

  如果调用的是二维数组中的元素a,而元素a任然是数组,根据元素a的数组类型

  决定内部元素的默认初始化值,与一维数组的规定相同

  如果输出元素a,其值决定于是否初始化过,如果初始化过,则输出地址值,如果

  没初始化过,则为null

数组一旦初始化,其长度就是确定的,而其长度不可改变

万事万物皆对象

类的属性默认值和数组元素默认值一样

面向对象思想的体现一:类和对象的创建

 1.创建类,即为提供类的内部结构:属性和方法

 2.创建类的对象(类的实例化,实例化类)

 3.可以通过“对象.属性”或“对象.方法”调用相关功能

 特例:Math.sqrt(..) / Math.random()

如果创建了一个类的多个对象,那抹多个对象之间是彼此独立的。即每个对象,都拥有一套自己的属性

当通过其中一个对象修改其属性值时,不会影响其他对象相同属性值

堆:new 出来的结构,数组,对象

栈:局部变量

变量的分类:按照数据类型的分类:基本数据类型(8个) vs 引用数据类型(3个:数组、类、接口)

       按照变量在类中声明的位置不同:成员变量(或属性) vs 局部变量

类中属性的使用

  成员变量(或属性) vs 局部变量

1.相同点:①声明的格式是相同的:数据类型 变量名 = 初始化值

     ②先声明后使

     ③变量都有作用域

2.不同点:①类中声明的位置不同

      成员变量:在类的一对{}内直接声明的变量

     局部变量:方法内声明的,方法的形参位置声明的,构造器内声明的,代码块内声明的都是局部变量

     ②成员变量可以在数据类型前声明权限修饰符,而局部变量是不可以声明权限修饰符的

      补充:权限修饰符有哪些?public 、private、protected、缺省

     ③成员变量:声明时,有默认初始化值。也就是说,我们在定义成员变量时,可以不显示的赋值

     整形:byte,short,int,long : 0

     浮点型:float,double : 0.0

     字符型:char :0 (或表示为‘\u0000’)

     布尔类型: boolean : flase

     引用数据类型:null

      局部变量:没有默认初始化值。必须要在调用前,显示的赋值

    特别的:方法的形参。此局部变量在方法内调用前,不需要赋值。他的赋值,是在方法调用时。

     ④二者在内存中存放的位置,是不同的

      成员变量:存放在堆空间中

      局部变量:存放在栈空间中

属性是依托于对象存在的

类中方法的使用:

​ 方法:类中声明的一个结构,能够实现具体功能。Arrays.sort(int[] arr) / Arrays.binarySearch(int[] arr,int value)

1.public void eat(String food){}

​ public void show(){}

​ public int returnAge(){}

​ public String info(String nation){}

2.方法声明的格式:

​ 权限修饰符 返回值类型 方法名(形参列表){

​ 方法体

}

​ 3.具体说明:

   ①权限修饰符:可以理解为所被修饰的结构能被调用的范围的大小

    有如下的权限修饰:public,protected,缺省,private

   ②关于返回值类型:没有返回值:void

            有返回值:指明具体的返回值类型

如果方法声明时,有返回值,那抹我们就需要在方法执行中,返回具体的满足相应类型的变量或者常量。比如return 1 或者 return index

   说明:如果方法有返回值,方法中一定有return !

   ③方法名:属于标识符。需要命名时,满足标识符的命名规则和规范,“见名知意”

   ④.形参列表:可以声明0个,1个或者多个变量,如果声明了多个变量,中间用“ ,”分开

   ⑤.方法体:我们调用方法时,要执行的逻辑。

    方法的功能主要体现在方法体上。

  1. ①方法中调用当前类的属性或方法。(如果方法A中调用方法A:递归方法)

    ②在方法体中,可以使用关键字:return ,reutrn的意思:返回,跳出

    ③ 在方法内,不能再定义方法

同一个包下,不允许定义两个同名的类

在static方法中,调用非static的方法,需要使用对象调用

DRUID介绍

   DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池(据说是目前最好的连接池,不知道速度有没有BoneCP快)。

阅读全文 »

匿名对象:

  1.匿名对象:创建类的对象,但是并没有声明给一个对象引用

   2.匿名对象只能调用一次

  3.应用,常常在调用方法时,将一个匿名对象作为参数传递过去

方法重载:(overload) loading…

 1.定义:在同一个类中,相同的方法名,不同的参数列表的方法之间,彼此构成重载

  举例:Arrays 中的sort(Xxx[] xxx) / System.out.println(Xxx xxx)

  总结:两同一不同,一不同:①参数个数不同 ②参数类型不同

 2.方法的重载与方法的形参的变量名没有关系! 与方法是否有返回值也没有关系

 测试题:区分方法的重载(overload)和方法的重写(override / overwrite)

 3.如何确定调用的是哪一个类的方法? 指明方法名——>指明参数的类型

可变个数形参方法的使用:jdk5.0新特性

  • 可变个数形参的格式:数据类型 … 变量名
  • 可变个数形参的方法在调用时,给可变个数的形参赋值时,可以赋值的个数为:0个,1个,……..
  • 可变个数形参的方法与同名方法之间彼此构成重载
  • 可变个数形参的方法与形参类型相同的数组方法不能同时出现在类中
  • 可变个数形参必须声明方法形参的最后一个参数
  • 在一个方法的形参位置,最多只能声明一个可变长度形参
变量的值传递机制:

 如果赋值的是基本数据的变量,则传递的是基本数据类型变量所保存的具体的数值

 如果赋值的是引用数据类型变量,则传递的是引用数据类型变量所保存的地址值

方法的参数传递机制:值传递

1.形参:方法在声明时,指定的参数

 实参:方法调用时,具体给形参赋的值,就是实参

2.如果方法的形参是基本数据类型的变量,则方法调用时,传递的实参即为基本数据类型变量所保存的具体的值

如果方法的形参是引用数据类型的变量,则方法调用时,传递的实参即为引用数据类型变量所保存的地址值

面向对象的特性之一:封装与隐藏 3w : what ? why ? how ?

1.问题的引入?

我们在创建一个类的对象以后,通过“对象.属性”的方式,可以给对象的属性赋值,对此属性的赋值,是有限制的,比如:数据类型和数据类型储存范围的限制。

但在实际问题中,还通过需要额外的限制。同时这些额外的限制,不可能在属性的声明中加上限制逻辑。

那抹我们只能考虑通过方法,对属性的赋值进行额外的限制,同时,我们必须禁止再直接通过 “对象.属性” 的方法,对属性进行赋值

2.封装性的体现(狭义上的体现)

  私有化(private)类的属性,同时,提供公共的(public)设置(setXxx())和获取(getXxx())的方法

3.封装性的体现:(广义上的体现)

  java规定的4种权限修饰符:(从小到大) private 缺省 protected public \

  java规定的4种权限可以用来修饰类及类的内部结构:属性,方法,构造器,内部类

具体来讲:这4种权限都可以用来修饰类的内部结构:属性,方法,构造器,内部类,只能使用 缺省 或者 public 修饰类