实现函数对象的几种方式:
- C语言的函数指针
- lambda表达式
- 函数式接口
函数对象主要用于策略模式.只用一次的话,使用匿名内部类;多次使用的话,可以导出成一个成员域(static final修饰)
实例:
java.util.Comparator
实现函数对象的几种方式:
- C语言的函数指针
- lambda表达式
- 函数式接口
函数对象主要用于策略模式.只用一次的话,使用匿名内部类;多次使用的话,可以导出成一个成员域(static final修饰)
实例:
java.util.Comparator
当类实现接口时 ,接口就充当可以引用这个类的实例的类型(type)。因此,类实现了接口,就表明客户端可以对这个类的实例实施某些动作。为了任何其他目的而定义接口是不恰当的。
有一种接口被称为常量接口(constant interface),它不满足上述条件。这种接口没有方法,只有静态final域。常量接口模式是对接口的不良使用。这样做不仅会暴露该类的实现细节到导出API中,还会产生一个更糟糕的情况。就是在将来的发行版中,如果类不再需要使用这些常量,它依然必须实现这个接口,以确保二进制兼容性。如果非final类实现了常量接口,它的所有子类的命名空间也会被接口中的常量所“污染”。
Java平台类库中有几个常量接口,例如java.io.ObjectStreamConstants。这些接口应该被认为是反面的典型,不值得效仿。
1.如果常量与某个现有类或接口紧密相关,就应该把这些常量添加到这个类或接口中。
2.如果这些常量可以被看作枚举类型的成员,就应该用枚举类型(enum type)。
3.用不可实例化的工具类( utility class)。使用静态导入(import static)避免常量修饰.
1 | private static <E> void varargs(Object obj,E...varargs){ |
泛型编程只能接受引用类型
打印数组tostring,会导致没有意义的字符结果
可变参数每次调用都会导致有一次数组分配和初始化
EnumSet静态工厂最大限度地减少创建枚举集合的成本
1 | public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) { |
Lambda没有文档和名字,如果不能方法体太长或者不能自解释的话,那么就不要放到lamdba中。
Lambda不能使用this访问自身。this在Lambda是访问的外部类。如果要在方法体中访问自身的话,那么就不能使用Lambda
不要在创建函数对象的时候使用匿名内部类,除非创建的对象不是函数式接口。
1 | public enum Operation { |
将数组中的不用的元素设置为null,尽早垃圾回收
缓存可以使用WeakHashMap.及时将key进行回收。
使用定时器将缓存中不用的项目删除或者LinkedHashMap.removeEldestEntry()
1 | import com.alibaba.druid.support.json.JSONUtils; |
输出:1
2{"beijing":"haid","beijing2":"haid2","beijing3":"haid3"}
{"beijing2":"haid2","beijing3":"haid3","beijing4":"haid4"}
将监听器回调及时的清除,可以使用WeakHashMap.
使用内存Heap Profiler进行对象分析。
引用:https://www.cnblogs.com/AlanLee/p/6122416.html
避免使用new String("zzz")
创建对象,避免创建对象
优先使用基本类型.避免装箱引起的内存消耗.
尽量用静态工厂,例如Boolean.valueOf() Integer.valueOf();hashmap.keySet() 因为构造器会创建对象,会消耗内存空间。
参考:http://www.importnew.com/6605.html
Builder会增加个类代码,这也意味着开发者在给类增加属性时有时会忘记给该属性添加支持的builder。为了克服这个问题,通常我会将builder嵌套到类中,这样可以很容易地发现哪个相关的builder需要更新
构建对象时,如果碰到类有很多参数——其中很多参数类型相同而且很多参数可以为空时,我更喜欢Builder模式来完成。当参数数量不多、类型不同而且都是必须出现时,通过增加代码实现Builder往往无法体现它的优势。在这种情况下,理想的方法是调用传统的构造函数。再者,如果不需要保持不变,那么就使用无参构造函数调用相应的set方法吧。
必要参数写到构造器里
如果要实现builder的重用性,可以讲初始化工作放到目标类中。不需要重用的话,可以讲初始化工作在builde创建出来的时候,就将实例创建出来。
将构造器 设置为Private并且要抛出异常,就可以解决这个问题.
1 | public class UtilsClass { |
转载自: https://mp.weixin.qq.com/s/f23I1kyJQoNPu6Ntrx0S6g
读后感:
Java1.6
为Synchronized做了优化,增加了从偏向锁到轻量级锁再到重量级锁的过度,但是在最终转变为重量级锁之后,性能仍然较低. 这其中用到了CAS机制。
CAS优点
- Synchronized属于悲观锁,悲观地认为程序中的并发情况严重,所以严防死守。CAS属于乐观锁,乐观地认为程序中的并发情况不那么严重,所以让线程不断去尝试更新。
- 避免了context switch
CAS缺点
- CPU消耗较大,不适合高并发场景(因为冲突太多,失败率高)。
- ABA问题
- 不能保证代码块的原子性。例如不能保证多个变量同时更新.
1 | public int size() { |
Field的public void setAccessible(boolean flag) 说明
* Set the {@code accessible} flag for this object to * the indicated boolean value. A value of {@code true} indicates that * the reflected object should suppress Java language access * checking when it is used. A value of {@code false} indicates * that the reflected object should enforce Java language access checks.
如果flag设置为true,那么就会压制java语言的访问校验。
Java集合的稳定性(order)与有序性(sort)调研.
合理利用好集合的有序性(sort)和稳定性(order),避免集合的无序性(unsort)和不稳定性(unorder)带来的负面影响。 说明:
有序性是指遍历的结果是按某种比较规则依次排列的。
稳定性指集合每次遍历的元素次序是一定的。如:ArrayList,LinkedList是order/unsort;HashMap是unorder/unsort;TreeSet是order/sort.
1 | public static void main(String[] args) { |
返回值
1 | call method |