类加载器,List,map,set集合,线程

什么是类加载器

类加载器是一个用来加载类文件的类。Java源代码通过javac编译器编译成类文件。然后JVM来执行类文件中的字节码来执行程序。类加载器负责加载文件系统、网络或其他来源的类文件。有三种默认使用的类加载器:Bootstrap类加载器、Extension类加载器和System类加载器(或者叫作Application类加载器)。每种类加载器都有设定好从哪里加载类。

先说说数组Array和集合的区别:

   (1)数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型)

   (2)JAVA集合可以存储和操作数目不固定的一组数据。

   (3)若程序时不知道究竟需要多少对象,需要在空间不足时自动扩增容量,则需要使用容器类库,array不适用。  

  FYI:使用相应的toArray()和Arrays.asList()方法可以相互转换。

一、集合

  集合类存放于java.util包中。
  集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。
  集合类型主要有3种:set(集)、list(列表)和map(映射)。

一、这三者什么关系呢

Collection
List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
Set
Map
├Hashtable
├HashMap
└WeakHashMap

Collection接口
  Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
  所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个 Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。
  如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:

Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
  Object obj = it.next(); // 得到下一个元素
} 

  iterator接口:

  由Collection接口派生的两个接口是List和Set。

2.Set

  Set接口同样是Collection接口的一个子接口,它表示数学意义上的集合概念。Set中不包含重复的元素,即Set中不存两个这样的元素e1和e2,使得e1.equals(e2)为true。由于Set接口提供的数据结构是数学意义上集合概念的抽象,因此它需要支持对象的添加、删除,而不需提供随机访问。故Set接口与Collection的接口相同。

  Set接口继承Collection接口,而且它不允许集合中存在重复项。所有原始方法都是现成的,没有引入新方法。具体的Set实现类依赖添加的对象的equals()方法来检查等同性。

  HashSet: 使用HashMap的一个集的实现。虽然集定义成无序,但必须存在某种方法能相当高效地找到一个对象。使用一个HashMap对象实现集的存储和检索操作是在固定时间内实现的.

  TreeSet: 在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap.

  为优化 HashSet 空间的使用,您可以调优初始容量和负载因子。TreeSet 不包含调优选项,因为树总是平衡的,保证了插入、删除、查询的性能为log(n)

  HashSet 和 TreeSet 都实现 Cloneable 接口。

  当您要从集合中以有序的方式抽取元素时,TreeSet实现会有用处。为了能顺利进行,添加到TreeSet的元素必须是可排序的

List

   List接口继承了Collection 接口以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。

 实际上有两种List: 一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的LinkedList,它并不是为快速随机访问设计的,而是具有一套更通用的方法。

  List : 次序是List最重要的特点:它保证维护元素特定的顺序。List为Collection添加了许多方法,使得能够向List中间插入与移除元素(这只推荐LinkedList使用。)一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插入和移除元素。    ArrayList : 由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。ListIterator只应该用来由后向前遍历ArrayList,而不是用来插入和移除元素。因为那比LinkedList开销要大很多。

  LinkedList : 对顺序访问进行了优化,向List中间插入与删除的开销并不大,随机访问则相对较慢。(使用ArrayList代替。)还具有下列方法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。

  Vector:实现一个类似数组一样的表,自动增加容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中一样。你也可以用一个迭代器从一个Vector中检索对象。Vector是唯一的同步容器类!!当两个或多个线程同时访问时也是性能良好的。

  Stsck: 这个类从Vector派生而来,并且增加了方法实现栈!一种后进先出的存储结构。

  面向位置的操作包括插入某个元素或 Collection 的功能,还包括获取、除去或更改元素的功能。在 List 中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置。

List和Set对比  

  Linked 改快读慢

  Array 读快改慢

  Hash 两都之间

  Collection是集合接口
    |————Set子接口:无序,不允许重复。
    |————List子接口:有序,可以有重复元素。

    区别:Collections是集合类

  Set和List对比:
    Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
    List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

    Set和List具体子类:
    Set
     |————HashSet:以哈希表的形式存放元素,插入删除速度很快。

    List
     |————ArrayList:动态数组
     |————LinkedList:链表、队列、堆栈。

    Array和java.util.Vector
    Vector是一种老的动态数组,是线程同步的,效率很低,一般不赞成使用。

Map

  Map接口不是Collection接口的继承。而是从自己的用于维护键-值关联的接口层次结构入手。按定义,该接口描述了从不重复的键到值的映射。

  我们可以把这个接口方法分成三组操作:改变、查询和提供可选视图。

改变操作允许您从映射中添加和除去键-值对。键和值都可以为null。但是,您不能把Map作为一个键或值添加给自身

Map.Entry 接口

  MapentrySet()方法返回一个实现Map.Entry接口的对象集合。集合中每个对象都是底层Map中一个特定的键-值对。

  通过这个集合迭代,您可以获得每一条目的键或值并对值进行更改。但是,如果底层MapMap.Entry接口的setValue()方法外部被修改,此条目集就会变得无效,并导致迭代器行为未定义。

HashMap 类和 TreeMap 类

  “集合框架”提供两种常规的Map实现:HashMapTreeMap。和所有的具体实现一样,使用哪种实现取决于您的特定需要。在Map中插入、删除和定位元素,HashMap是最好的选择。但如果您要按顺序遍历键,那么TreeMap会更好。根据集合大小,先把元素添加到HashMap,再把这种映射转换成一个用于有序键遍历的TreeMap可能更快。使用HashMap要求添加的键类明确定义了hashCode()实现。有了TreeMap实现,添加到映射的元素一定是可排序的。

  为了优化HashMap空间的使用,您可以调优初始容量和负载因子。这个TreeMap没有调优选项,因为该树总处于平衡状态。

  HashMapTreeMap都实现Cloneable接口。

  Hashtable类和Properties类是Map接口的历史实现。

  HashTable: 实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。

  HashMap: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。

 

  WeakHashMap: 实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。

 

  TreeMap: 实现这样一个映象,对象是按键升序排列的。

 

线程相关

什么是线程?什么是进程?

进程是运行着的一个应用程序,一个应用程序一旦运行就是一个进程,进程是分配cpu的最小单位。

线程是进程的一个实体,是进程的一条执行路经,线程是程序执行的最小单位。

线程和进程的区别?

  • 进程是资源分配的最小单位,线程是程序运行的最小单位。
  • 一个进程可以包含多个线程,但至少有一个线程,所有的线程共享进程的资源。
  • 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。

④进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

创建线程的几种方式?

  • 继承Thread类
  • 实现Runnable接口的run方法
  • 实现Callable接口

 

线程的优先级?

我们在公交车站乘坐公交车,如果有2人同时上车,只有一个座位,但是这个时候其中一个是孕妇,那自然是她优先坐了,这就是优先级的概念。在线程中,谁的优先级高,谁执行的次数就会提高。在代码中可以给线程设置优先级,支持的3个级别的优先级是1、5、10。

线程的生命周期?

线程一共有5种状态。

新建、就绪、运行、堵塞、死亡。

新建:当我们去新建了一个Thread类的实例的时候,该线程就进入了新建状态。此时,此时可以调用start方法进入就绪状态。

就绪:该状态下的线程会等待cpu分配资源,准备进入运行状态。

运行:线程获得cpu正在执行任务,除非此线程主动放弃cpu资源(yelid)或者有优先级更高的线程介入,否则线程将一直执行结束。

堵塞:由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。

正在等待:调用wait()方法。(调用motify()方法回到就绪状态)

死亡:当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

自然终止:正常运行run()方法后终止

异常终止:调用stop()方法让一个线程终止运行

什么是线程池?

什么是线程的同步和异步?

线程同步是多个线程同时访问同一资源,等待资源访问结束,浪费时间,效率低   

  线程异步:访问资源时在空闲等待时同时访问其他资源,实现多线程机制

什么是线程安全?

出现线程安全问题主要是由于多个线程同时访问共享资源,并且操作共享数据的代码有多条。

本地线程:ThreadLocal

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值