Java基本数据结构

2023-08-09  本文已影响0人  Atomic

上篇文章我们基本介绍了Java相关的发展过程,那么,我们使用Java就必须了解其具体的语法和基本的数据结构以及相应的关键字
基本语法是所有编程语言比较通用的,这边不过多的介绍,那么我们主要从数据结构以及Java中常用的关键字来举例,顺便提出一些遇见过的面试题

基本数据结构

一. 封装类型和基本数据类型

Java基本数据类型.png

针对基本数据类型(primitive type),Java支持自动拆箱和自动装箱

自动装箱的弊端

Integer sum = 0;
 for(int i=1000; i<5000; i++){
   sum+=i;
}

## 这里会发生自动拆箱和装箱
int result = sum.intValue() + i;
Integer sum = new Integer(result);

拆箱和装箱问题

为什么要使用装箱和拆箱?既然会出现上述弊端,为何不直接使用基本数据类型就好?

这篇文章介绍的挺好 java的装箱与拆箱

缓存的对象

Java中对于小整数范围内的整数(-128到127),会进行缓存,因此同样的整数值在缓存范围内时,它们对应的包装类型对象是同一个。但是超过缓存范围的整数值,即使值相等,它们对应的包装类型对象也不相同。


Java整型缓存.png

Integer.valueOf(int i) 源码

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

IntegerCache 类源码

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

Java中另一个节省内存的例子就是 字符串常量池

自动拆箱、装箱过程中,会遇到 == 和 equals 两种比较大小,不管是int和Integer,还是int和Long,这里不做详细描述,可以手动实验
这篇博主提出的面试题跳转

Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;

System.out.println(c == d);
System.out.println(e == f);
System.out.println(c == (a + b));
System.out.println(c.equals(a + b));
System.out.println(g == (a + b));
System.out.println(g.equals(a + b));
System.out.println(g.equals(a + h));

结果
true
false
true
true
true
false
true

引用数据类型

二、String

String的考察,也是前期面试的高频题,弄懂String才能更高效的开发
什么是String

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

 private final char value[];

 private int hash; // Default to 0

 private static final long serialVersionUID = -6849794470754667710L;

}

首先,它是一个类,是引用数据类型,不是基本数据类型;
它是 final 修饰的,说明它是不可修改的;即一旦一个 String 对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
它的底层是通过 final char value[] char数组来保存数据的

但是,我们通常理解的String,应该都是可以修改的才对,其实,这里底层创建了新的String对象

String、StringBuilder、StringBuffer的区别
两个可变字符串类 StringBuffer 和 StringBuilder,中文翻译为“字符串缓冲区”
StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能

其底层的原理创建对象的过程,还需要涉及JVM的知识,也就是创建对象的过程在堆内存是一个对象还是多个对象

String类,如果用赋值操作,会在堆内存生成新的对象,例外:字符串常量池;StringBuilder、StringBuffer是只有一个对象在堆内存

使用环境:
操作少量的数据使用 String
单线程操作大量数据使用 StringBuilder
多线程操作大量数据使用 StringBuffer

什么是字符串常量池?
这篇文章介绍的非常详细,文章归纳的话,在首次使用某个字符串字面量时,字符串字面量以真正的String对象的方式存放在 字符串常量池(String Pool)
Java字符串字面量是何时进入到字符串常量池中的

new String("Hello");到底创建了几个对象

类class引用

三、接口类型

Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

java接口和类有什么区别?

四、枚举类型

在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠.。枚举是一个被命名的整型常数的集合,枚举在日常生活中很常见,例如表示星期的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY就是一个枚举。

下面这篇文章介绍的比较详细
枚举类型的介绍

Enumset
EnumSet是用于枚举类型的专用Set实现。EnumSet中的所有元素必须来自单个枚举类型,该类型在创建集时显式或隐式指定。枚举集在内部表示为位向量,这种表现非常紧凑和高效。它不允许有空值,如果是试图插入空值,将会抛出NullPointerException异常,但是可以检测是否含有空值。通之前讲的其他集合一样,他也是非同步的。

EnumSet的迭代器方法返回的迭代器以其自然顺序(枚举类中枚举常量的顺序)遍历元素。返回的迭代器是弱一致的:它永远不会抛出ConcurrentModificationException,它可能会也可能不会显示迭代进行过程中对集合所做的任何修改的影响。

总结:

EnumSet简析

五、数组类型

数组的定义和初始化

int[] arr = new int{1,2,3,4,5};
int[] arr1 = {1,2,3,4,5};
int arr2[] = new int[10];

数组和链表的优缺点?

上一篇下一篇

猜你喜欢

热点阅读