Java基本数据结构

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

基本数据结构

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

Java基本数据类型.png

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

  • 装箱:Java自动将原始类型值转换成对应的对象,比如,将int变量转换成Integer对象
  • 拆箱:反之,将对象类型转换成对应的原始类型,Integer对象转换成int类型值


    Java的装箱拆箱.png

自动装箱的弊端

  • 谨防多余变量,导致内存消耗
Integer sum = 0;
 for(int i=1000; i<5000; i++){
   sum+=i;
}

## 这里会发生自动拆箱和装箱
int result = sum.intValue() + i;
Integer sum = new Integer(result);
  • 精度丢失问题

拆箱和装箱问题

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

  • 对象引用:基本类型不是对象,无法使用对象引用,而包装类型是对象,可以通过引用来操作。
  • 泛型:泛型不能使用基本数据类型,必须使用包装类型。如,使用List<Integer>来存储一组整数,而不是使用List<int>。
  • null值:基本类型不能为null,而包装类型可以为null。
  • 类型转换:包装类型提供了许多类型转换方法,例如:将字符串转换为整数或浮点数等,这些方法非常方便。
  • 方法重载:方法重载可以使用不同的参数类型,但是基本数据类型和其对应的包装类型在方法中被认为是相同的类型,因此可以在方法中使用它们进行重载。

这篇文章介绍的挺好 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引用

  • Object:Object是一个很重要的类,Object是类层次结构的根类,每个类都使用Object作为超类,所有对象(包括数组)都实现这个类的方法。用Object可以定义所有的类
  • String:String类代表字符串,Java 程序中的所有字符串字面值(如"abc")都作为此类的实例来实现。检查序列的单个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本、在该副本中、所有的字符都被转换为大写或小写形式。
  • Date:Date表示特定的瞬间,精确到毫秒。Date的类一般现在都被Calendar 和GregorianCalendar所有代替
  • Void:Void 类是一个不可实例化的占位符类,它保持一个对代表 Java 关键字 void 的 Class 对象的引用。

三、接口类型

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

java接口和类有什么区别?

  • 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
  • 除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
  • 接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

四、枚举类型

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

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

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

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

总结:

  • EnumSet中的所有元素必须来自单个枚举类型
  • EnumSet不允许有空值,但是可以检测是否含有空值
  • EnumSet的迭代器方法返回的迭代器以枚举类中枚举常量的顺序遍历元素,且永远不会抛出ConcurrentModificationException
  • EnumSet是非同步的
  • EnumSet是一个抽象类,我们对他的操作实际是对它的两个实现类JumboEnumSet或者RegularEnumSet其中之一做的操作。具体判断为,如果枚举类中的枚举常量大于64个,则使用JumboEnumSet,反之使用RegularEnumSet
  • EnumSet是使用位向量实现的,即使用一个位表示一个元素的状态

EnumSet简析

五、数组类型

数组的定义和初始化

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

数组和链表的优缺点?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容