天天看点

java学习(4)-一些集合类和基础类的简单描述

文章目录

    • 说明
    • Scanner类
    • 匿名类对象
    • Random类
    • 对象数组
    • ArrayList
    • LinkedList
    • HashSet
    • LinkedSet
    • TreeSet
    • HashMap
    • HashTable
    • TreeMap
    • String类
    • ==和equals的区别
    • static关键字
    • Arrays类
    • Math类

说明

因为是个人复习java的总结,所以结构稍显杂乱,有些语句过于口语化.

对于被标题描述误导进入的读者表示抱歉,已尽量修改描述至恰当.

帮助文档中可以查找所有的api 注意学会自主查看文档

Scanner类

用于监视键盘输入,获取内容到程序中,也就是输入的api

首先需要导入scanner的包

一般语法为

Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
           

  具体看api 注意谨慎使用close()方法,因为sc获取的其实是同一个final的输入流,一旦close之后再次获取就还是那个被关闭的状态,就无法获取输入内容.

匿名类对象

其实就是在new对象的时候不对其进行赋值到栈中索引的一种创建对象方式,只是使用一次之后就不能再找到这个对象.

Random类

用来生成随机数的类,需要导入util下Random包

基本语法

Random r = new Random();
int num = r.nextInt();
           

  有正负两种范围,具体范围是左闭右开的,构造方法为单个参数的时候确定的是右范围,左范围为0.

具体使用见api

对象数组

其实就是将对象存放进数组中,然后获取数组中内容再调用方法.

但是数组一旦创建,长度就无法改变,所以接下来是ArrayList等更为方便的类

List Map Set Queue其实都是collection的子接口,而不是具体的实现类,具体的实现类在接口之下实现

List总共分为ArrayList,LinkedList和Vector

其中ArrayList和Vector的底层都是用数组实现,都是可变长度的数组,只是ArrayList线程不安全,Vector线程安全但是效率相对较低

ArrayList

  ArrayList其实就是一个可变长度的数组,具体构造方法等见api 之后了解api不再提

  ArrayList可以使用泛型

  泛型就是对于集合中元素数据类型的限制,限制之后只能往这个集合中传入特定类型的数据.基本写法:ArrayList list = new ArrayList<>();在jdk1.7之后可以省略右边泛型的类型书写

  泛型需要注意限制的类型必须是包装类,即在包中的类对象,拥有一些方法或属性,而不能是基本数据类型,int要使用Int

  使用之后可以直接传入int类型数据,包装类会自动包装之后存储,在输出的时候在自动转换成基本数据类型输出.

  ArrayList添加元素使用的是add()方法,这个方法返回类型是boolean,因为要判断泛型

其中常用的方法有 get(), remove(), size().

  当直接打印ArrayList对象的时候,得到的是所有内容的集合,区别于数组打印得到的是地址

  ArrayList虽然是可变的数组,但是在使用的时候一般会先给定一个范围,避免在扩大数组的时候造成不必要的大量的数组复制时间.

  最后需要注意ArrayList不是线程安全的,其底层其实是基于数组实现的,因此其访问的速度比较快,相比于LinkedList需要顺序查找,ArrayList可以直接访问而不需要移动指针.

LinkedList

  LinkedList其实就是双向链表,其组成就是有前后指向的一串连接数据表

  因此其查找速度不是很好,但是如果对元素进行插入的时候,其相比于ArrayList速度要快很多,ArrayList需要在插入元素的时候,移动后面受到影响的元素,而LikedList可以直接通过改变前后指向在任意位置插入元素,当然末尾插入元素的开销两者是一样的.删除两个list也是一样的道理

Set集合包含HashSet,LinkedSet,TreeSet.

  都是不允许存在重复对象的容器,null值也只能唯一.其中HashSet和LinkedSet是无序的,而TreeSet是通过compare()进行一个比较实现的有序

HashSet

  底层是哈希表,线程不安全

  其本质是一个哈希表来存储的结构,对于存入的元素会进行hashcode的判断,如果不同则认为是不同的元素,但是hash算法的设置不同,可能造成hash值相同,这时会调用equal判断是否重复,然后对于不重复的元素存在多种方法,向后顺延或者再次hash或者价值.

  因其工作原理,需要注意对于自定义类,要重写其hashCode()从而使得该类对象具有不同的hash值,并且再重写equal方法,这样有助于在hash判断出现偶然是,equal判断两个对象是否是你认为的相同

LinkedSet

本质上是一个按照插入顺序排序的双链表,底层是HashMap,线程不安全

TreeSet

其实就是一个用tree结构来维护的set,其中对象使用升序来排序,访问和遍历速度很快

需要重写存入的自定义类对象的compareTo来实现某种方式的排序

Map分为HashMap,HashTable,TreeMap等

其实本质上是键值的存储模式,键作为标识控制存入,具有唯一性,而值可以任意

HashMap

  其底层的本质实际上是数组加链表.首先由key进行hash然后获取到存放的位置,再对存放位置尽心链表组接,但是对于过长的链表jdk8之后会将数据存到红黑树中,以增加检索速度.

  因为其查询时,实际上是根据key直接获取到存储位置,然后在存储位置遍历获取到值,如果链表太长,这么效率就会降低,就失去了原本的意义.

HashTable

其实就是对于HashMap的补充,是一个线程安全版本的集合

TreeMap

其实也是根据key来进行树结构的存储

对于Map的遍历一般使用entrySet()来辅助进行,因为这个函数返回的数据是键值组合形式的,在遍历中有益于根据键获取值.

例子如下:

Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Entry e =(Entry) it.next();
System.out.println("键"+e.getKey () + "的值为" + e.getValue());
}
           

String类

  所有使用双引号包含的内容都作为String类的实例,其效果类似char[],但是其底层是用byte[]实现的

  字符串是共享的,因为字符串是存储在堆中的字符常量池,当重复创建的时候会指向相同的地址.其实就是把字符串看作是一个类,把所有字符串类型的数据看作是对象.又因为上面提到所有双引号的数据都看作是String类的实例,可以想到其实就是其他类new对象相同的原理.双引号这种创建对象方法就是在堆中开辟一块区域存放String对象,而这个对象实际上存放的也是地址,因为其底层是byte[]实现的.那么对于相同的字符串来说,他们其实就是相同的对象,所以指向的是同一个对象地址,对象地址又指向同一个byte[].

  但是需要注意,双引号这种创建对象方式和使用String类构造方法创造对象就存在区别,双引号的对象是存放在堆中固定的字符串常量池区域,而使用构造方法创造的对象则是存放在堆中,因此两者即使创造的是相同的字符串内容,他们也不会指向同一个对象.

==和equals的区别

  其实很简单,==比较的是地址值,所以堆两个对象比较的时候,比较的是两个对象在堆中的地址.String也是同理,对于字符串常量池中的比较也是地址,但是因为其实现方式,所以很像是比较两个字符串的内容,其实不是.

 emsp;equals则是比较字符串中的内容,因此对于不同的对象如果拥有相同的内容也会相等.

 emsp;另外需要注意使用问题,推荐使用String常量.equals(String对象)这种方式来书写,也就是”hello”.equals(str);因为这么写的话,对于调用equals方法的对象而言一定不为空.如果反过来,那么对于对象变量而言我们有可能在书写或者输入的时候造成对象为空,那么就会造成空指针异常.

static关键字

  就是标记类中的共享值,类所有的对象都共用同一个.

  其修饰成员变量的时候,那么就可以达到所有对象拥有同一个变量,比如说计数变量.

  其修饰成员方法的时候,就可以达到不通过对象调用方法的效果,也是类中所有对象的操作.调用不再需要创建对象调用.

  使用过程中需要一个问题,静态不能直接访问非静态.可以从内存上可以理解,在加载一个类的时候在方法区就会加载一些类的方法和变量基本信息但不是地址,并且会加载类的静态变量和方法存储在方法区中的静态区,然后每次调用的时候都会栈中根据类在方法区找到对应静态内容,然后进行调用.

  所以这也造成了一个问题,线程安全问题.

  且静态不能使用this,因为静态是类调用而不是对象调用

  静态代码块就是在类当中使用static{}包装代码,使得这部分代码在使用该类的时候调用唯一的一次.也就是在加载该类的时候会调用一次静态代码块,但是如果再次使用这个类,因为已经加载就不会再次执行.

典型的用途就是对于静态变量的一次赋值.

Arrays类

  就是一个与数组操作有关的工具类,其中包括一些.toString() sort等方法,对数组进行快捷操作.

Math类

一些数学操作

ceil()向上取整

floor()向下取整

round()四舍五入   实际上是将原来的数字加上 0.5 后再向下取整

abs()绝对值

如有错误欢迎读者批评指正!!