Java总结2

对象的内存示意图

 

2、二维数组中 实质是一维数组,一维数组中存的是另外数组的地址

 

强制转换的例子

char c = '1';
int i = c - 48;
char c1 = (char)(i +48);
System.out.println(c);
System.out.println(i);
System.out.println(c1);
//1
//1
//1

权限修饰符

修饰词本类同一个包的类继承类其他类
private × × ×
无(默认) × ×
protected ×
public

protected 修饰的方法 在同一个包中调用 另一个包中继承本包的子类 import 子包就好

如果在子包中其他类中使用本包的方法需要在子包中重写方法才能使用

代码块

有局部代码块,构造代码块,静态代码块

局部代码块就是在方法中用{}括住的代码块;可以改变变量的生命周期,提前释放,提高效率

构造代码块和静态代码块在继承中的执行顺序

开始执行

父类静态代码块

子类的静态代码块

父类的构造代码块

父类的构造方法

子类的构造代码块

子类的构造方法

结束

且静态代码块只会加载一次 如下:定义两个类Person基类和Student子类

 static {
       System.out.println("我是静态人");
  }
  {
       System.out.println("我是人");
  }
   private String name;
   private int age;

   public Person(){
       System.out.println("我是构造人");
  }

   public Person(String name, int age) {
       this.name = name;
       this.age = age;
       System.out.println("我是构造人");
  }
Student s = new Student();
System.out.println("----");
Student student = new Student("haha",23);
//我是静态人
//我是静态学生
//我是人
//我是构造人
//我是学生
//我是构造学生
//----
//我是人
//我是构造人
//我是学生
//我是构造学生

final

final修饰变量:表示常量,变量只能赋值一次

修饰类:不能被继承

修饰方法:不能被覆盖

修饰对象的时候:内容是可以变的,就是地址不能变。

匿名内部类

1、不能具有static成员域和成员函数和类。

2、不能具有static final 修饰的引用类型。

3、不能有自定义的构造函数。(好像默认有)

4、不能具有静态代码块。

5、匿名内部类不能有类修饰符

1、内部类可以直接调用外部类的方法包括private修饰的方法,但是外部类不能直接调用内部类方法

2、方法中的局部变量,方法结束后这个变量就要释放掉,final保证这个变量始终指向一个对象。   首先,内部类和外部类其实是处于同一个级别,内部类不会因为定义在方法中就会随着方法的执行完毕而跟随者被销毁。问题就来了,如果外部类的方法中的变量不定义final,那么当外部类方法执行完毕的时候,这个局部变量肯定也就被GC了,然而内部类的某个方法还没有执行完,这个时候他所引用的外部变量已经找不到了。如果定义为final,java会将这个变量复制一份作为成员变量内置于内部类中,这样的话,由于final所修饰的值始终无法改变,所以这个变量所指向的内存区域就不会变。

注意,若使用JDK1.8,方法中内部类的方法是可以直接访问外部类的方法的局部变量,并且不需要声明为final类型

BigInteger和BigDecimal

java中long型为最大整数类型,对于超过long型的数据如何去表示呢.在Java的世界中,超过long型的整数已经不能被称为整数了,它们被封装成BigInteger对象.在BigInteger类中,实现四则运算都是方法来实现,并不是采用运算符.

float和double都是近似计算的 当商业计算时应该用BigDecimal

这两个类在计算是都是调用方法的比如add()

Date

        Date d = new Date();
       System.out.println(d);
       Date date = new Date(1000*60*60);
       System.out.println(date);
       long time = d.getTime();
       System.out.println(time /1000/60/60/24/365);
       d.setTime(1000*60*60);
       System.out.println(d);
//Thu Oct 29 18:11:55 CST 2020
//Thu Jan 01 09:00:00 CST 1970
//50
//Thu Jan 01 09:00:00 CST 1970

DateFormat

时间设置成自己喜欢的格式

        Date d = new Date();
       System.out.println(d);
       DateFormat date = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
       String s = date.format(d);
       System.out.println(s);
       String s1 = "2021年10月03日 13:41:33";
       d = date.parse(s1);
       System.out.println(d);

//Tue Nov 03 14:42:54 CST 2020
//2020年11月03日 14:42:54
//Sun Oct 03 13:41:33 CST 2021

Calendar

  Calendar c = Calendar.getInstance();
       c.add(Calendar.MONDAY,-2);//在当前时间月份-2
       c.add(Calendar.YEAR,1);//这个是年再加1
//c.set(2008,2,19);
       int year = c.get(Calendar.YEAR);
       int month = c.get(Calendar.MONDAY);
       int day = c.get(Calendar.DATE);
       System.out.println(year+"年"+month+"月"+day+"日");
//2021年8月3日

集合

Hashmap

hashmap的长度为什么是2的幂次方

我们首先可能会想到采用%取余的操作来实现。但是,重点来了:“取余(%)操作中如果除数是 2 的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%length==hash&(length-1)的前提是 length 是 2 的 n 次方;)。” 并且 采用二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是 2 的幂次方。

hashmap解决哈希冲突

JDK1.8 之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。

遍历

1、Iterator

        Map<Integer,String> map = new HashMap();
       map.put(1,"666");
       map.put(2,"啦啦啦");
       map.put(6,"哈哈");
       map.put(3,"慕阳");
       map.put(5,"无敌");
       map.put(4,"宝贝儿");

       Iterator<Map.Entry<Integer,String>> iterator = map.entrySet().iterator();
       while(iterator.hasNext()){
           Map.Entry<Integer,String> m = iterator.next();
//           System.out.println(m.getKey()+"--"+m.getValue());
           if(m.getKey() == 3){
               iterator.remove();
          }else {
               System.out.println(m.getKey()+"--"+m.getValue());
          }
      }
       System.out.println(map.get(3));
//1--666
//2--啦啦啦
//4--宝贝儿
//5--无敌
//6--哈哈
//null

迭代器删除元素是安全的,在运行过程中删除之后再遍历就不存在之前删除的值了

2、增强for

for(Map.Entry<Integer,String> entry: map.entrySet()){
           System.out.println(entry.getKey()+"---"+entry.getValue());
      }
//1---666
//2---啦啦啦
//3---慕阳
//4---宝贝儿
//5---无敌
//6---哈哈

   for(Map.Entry<Integer,String> entry: map.entrySet()){
//           System.out.println(entry.getKey()+"---"+entry.getValue());
           if(entry.getKey() == 3){
               map.remove(entry.getKey());
          }else {
               System.out.println(entry.getKey()+"---"+entry.getValue());
          }
      }

//1---666
//2---啦啦啦
//Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1584)
at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1617)
at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1615)
at mapdemo.MapDemo.main(MapDemo.java:29)

3、Lambda 方式

这三种效率都差不多

参考测试链接

原文地址:https://www.cnblogs.com/my-diary/p/13921111.html