Java basic
继承
子类可以新增父类没有的接口;子类拥有父类非private的属性,方法。
子类可继承父类中的方法,而不需要重新编写相同的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。子类也可以重写继承的父类的接口。方法重写与方法重载不同,方法的重载是方法的参数个数或种类或顺序不同,方法名相同。
关键字implements是一个类,实现一个接口用的关键字,它是用来实现接口中定义的抽象方法。实现一个接口,必须实现接口中的所有方法。使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)
还有几点需要注意:
(1)接口可以被多重实现(implements),抽象类只能被单一继承(extends)
(2)接口只有定义,抽象类可以有定义和实现
(3)接口的字段定义默认为:public static final, 抽象类字段默认是”friendly”(本包可见)
关键字super
在继承关系中,父类的成员变量、局部变量、方法被隐藏被子类常常覆盖,这时需要引用父类成员变量、局部变量、方法。 super.变量名,super.方法名,super.父类的构造方法;
关键字this
如果类的成员变量与局部变量重名,类的成员变量将被隐藏,如果要使用类的成员变量,需要使用this引用之。 this.变量名,this.方法名,this.父类的构造方法;
Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性。
is-a&&has-a
is-a( 是 "a" 小明是人类)表示的是属于得关系。比如兔子属于一种动物(继承关系)。
has-a( 有 "a" 汽车有轮胎) 表示组合,包含关系。比如兔子包含有腿,头等组件;就不能说兔子腿是属于一种兔子(不能说是继承关系)
对两个类之间"is a"或是"has a"关系的分析,有助于我们确定它们之间是否存在继承关系,避免设计上的错误,因而达到提高代码重用性的目的
JSON
JSON的基础是键值对,所有的键都是用双引号的!而值的类型就多了,常用的有字符串(必须使用双引号),真假值(true、false,注意"true"表示字符串!),数字(直接写1,2,3,4,不带单双引号)。
- 并列数据的集合(数组)用方括号("[]")表示。
- 并列的数据之间用逗号分隔。
- 映射的集合(对象)用大括号("{}")表示。
- 映射用冒号表示。
字符串转义
是将一些有特殊含义字符,标识为普通字符,函数解析字符串时看到转义字符,就不再对其做特殊处理,而是当做普通字符打印。例如引号 " 引号本身用于引用一段字符串,当函数看到引号,就知道跟在后面的是字符串,引号本身是不会直接打印出来的。那如果需要打印出引号来,就需要告诉函数,这个引号不要当做引用的特殊字符处理,当做普通字符打印就好,这里就需要一种通知的方式,反斜线字符就是起到一个标识符的作用。
匿名内部类
是内部类的简写。它的本质其实是一个带着具体实现父类或者父接口的匿名的子类对象。如果接口当中的实现类(或者父类的子类)在程序当中只需要使用唯一的一次,这种情况下可以使用匿名内部类。通常在方法的形式参数是接口或者抽象类时,一般将匿名内部类作为实参进行参数传递。
前提:匿名内部类必须【继承一个父类】或者【实现一个接口】,伴随着重写父类或者父接口当中的抽象方法。
java序列号
一.意义:
1.序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上。
2.通过网络传输,以达到以后恢复成原来的对象。
3.序列化机制使得对象可以脱离程序的运行而独立存在。
二.使用场景:
1.所有可在网络上传输的对象都必须是可序列化的。
2.所有需要保存到磁盘的java对象都必须是可序列化的。
所以基本上每个javaBean类都实现Serializeable接口。
三.实现方式:
实现Serializable接口或者Externalizable接口之一。
1.作用:
反序列化必须拥有class文件,但随着项目的升级,class文件也会升级为保证升级前后的兼容性:
java序列化提供了一个serialVersionUID 的序列化版本号,只有版本号相同,即使更改了序列化属性,对象也可以正确被反序列化回来。
2.不指定版本号的隐患:
序列化版本号如果不指定,JVM会根据类信息自己计算一个版本号,这样随着class的升级,就无法正确反序列化;
Java common
if条件判断
先按照运算符的优先级来,同级的从左到右依次。如果是 && 运算,前面的有一个不满足,后面的不会再判断;如果是 || 运算,前面的有一个满足,后面的也不会再判断。
所以把判断起来比较快的放第一个,这样执行效率高,一旦判断第一个不符合就不会再判断第二个了
hashmap
- remove不存在的key,不会抛出异常,返回null
- get一个不存在的值,不会抛出异常,获得的返回值为null。
- getOrDefault(Object key, V defaultValue):当Map中有这个key时,就使用这个key对应的value值,如果没有就使用默认值defaultValue。
keySet():HashMap、HashSet无序加入若干键值对,遍历 keySet 发现,似乎按照一定的顺序返回。HashMap 会先计算出 key 的 hash 值,再通过 hash & (length - 1) = index 得到具体插入位置的。
语法:keySet()
参数:该方法不带任何参数
返回值:该方法返回一个具有哈希映射键的集合
HashMap:我们最常用的Map,它根据key的HashCode 值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的key值为Null(多条会覆盖);允许多条记录的Value为 Null。非同步的。
TreeMap: 能够把它保存的记录根据key排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。
Hashtable: 与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。
LinkedHashMap: 保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。
ArrayList
- contains方法,底层调用了equals方法。ArrayList中的元素类型是String, 直接使用contains方法是没问题的,其他基本包装类型同它基本相同,都是比较的值, 因此也可以直接使用contains方法,使用其他引用类型需要用到contains方法时, 要重写equals方法。
- List中元素的值可以是null,此时此List不为空,
对象初始化
对象中的数据称为实例域,操纵数据的过程称为方法。如果在构造器中没有显式地给域赋予初值,那么就会被自动地赋为默认值:数值为0、布尔值为false、对象引用为null。
类中boolean 类型不初始化默认是false ,有是和否两种情况下时使用
类中Boolean 类型不初始化默认是null,有是、否、不知道三种情况下时使用
Date()
new Date()返回当日的日期和时间(时间并不是0点,而是当时实际的系统时间,且会到毫秒级,注意做时间比较的时候不能按秒级去看)
before()、after()方法:
before:d1.before(d2) 只有d1在d2之前才返回true 否则false 相当于 d1 < d2
after: d1.after(d2) 只有d1在d2之后才返回true 否则false 相当于 d1 > d2
这两个函数在不使用!(非运算符)的情况下且单独使用时 均不包含=的情况(如=)
除非对这两个函数足够了解 否则还是使用getTime()(返回自从GMT 1970-01-01 00:00:00到此date对象上时间的毫秒数来进行时间的比较才更清晰明了
BigDecimal
当需要将BigDecimal中保存的浮点数值打印出来,一般直接使用 BigDecimal.toString()方法即可以完成浮点数的打印。如:System.out.println( new BigDecimal("100.000").toString());程序的输出即为: 100.000
如果我们希望去除末尾多余的0,应该这么写:System.out.println( new BigDecimal("100.000").stripTrailingZeros().toString());其中,stripTrailingZeros()函数就是用于去除末尾多余的0的,但是此时程序的输出为: 1E+2是科学计数法。
想要避免输出科学计数法的字符串,用toPlainString()函数代替toString()。如:System.out.println( new BigDecimal("100.000").stripTrailingZeros().toPlainString());此时程序的输出就为 100
java方法参数传递
java中方法参数是值传递,不存在引用传递。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。
substring()
Java中也有截取字符串的方法,不过是从0开始算的 substring
sql中截取字符串就不一样了,是从1开始的 substr()
BeanUtils.copyProperties
BeanUtils.copyProperties可以用来进行类型转换。BeanUtils.copyProperties方法简单来说就是将两个字段相同的对象进行属性值的复制。如果 两个对象之间存在名称不相同的属性,则 BeanUtils 不对这些属性进行处理,需要程序手动处理。
这两个类在不同的包下面,而这两个类的copyProperties()方法里面传递的参数赋值是相反的。
一、 org.springframework.beans.BeanUtils
BeanUtils.copyProperties(a, b);
a拷贝到b
二、org.apache.commons.beanutils.BeanUtils
BeanUtils.copyProperties(a, b);
b拷贝到a
值传递
java中没有引用传递,只存在值传递。
值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
我们经常看到对于对象(数组,类,接口)的传递似乎有点像引用传递,可以改变对象中某个属性的值。但是不要被这个假象所蒙蔽,实际上这个传入函数的值是对象引用的拷贝,即传递的是引用的地址值,所以还是按值传递。
java 流
集合中单独取出对象中一个属性成为集合或数组
List stateNameList = dictEntityList.stream().map(DictEntity::getName).collect(Collectors.toList());
Long[] ids = dictEntityList.stream().map(DictEntity::getId).toArray(Long[]::new);
集合去重
dictEntityList.stream().distinct().collect(Collectors.toList());
orElse(null)表示如果一个都没找到返回null。【orElse()中可以塞默认值。如果找不到就会返回orElse中你自己设置的默认值。】
orElseGet(null)表示如果一个都没找到返回null。【orElseGet()中可以塞默认值。如果找不到就会返回orElseGet中你自己设置的默认值。】
区别就是在使用方法时,即使没有值 也会执行 orElse 内的方法, 而 orElseGet则不会。
lamda表达式
json数据转换
1、toJSONString
String str = JSON.toJSONString(Entity);
2、parseObject
Entity toObj = JSON.parseObject(str, Entity.class);
3、parseArray
String arrJson = JSON.toJSONString(entityList); List<Entity> arrList = JSON.parseArray(arrJson, Entity.class);
JSONObject转Map:有两种方式实现
- 1. 对于使用版本高于1.2.15的fastjson的可以尝试使用JSONObject的getInnerMap()方法
- 2. 对于老版本的fastjson可以使用递归的方式