160.说说数据类型之间的转换:
1 ) 如何将字符串转换为基本数据类型?
2 ) 如何将基本数据类型转换为字符串?
答:1 ) 调用基本数据类型对应的包装类中的方法parseXXX(String)或valueOf(String)即可返回相应基本类型;
2 ) 一种方法是将基本数据类型与空字符串(””)连接(+)即可获得其所对应的字符串;另一种方法是调用String 类中的valueOf(…)方法返回相应字符串
161.如何实现字符串的反转及替换?
答:方法很多,可以自己写实现也可以使用String或StringBuffer / StringBuilder中的方法。有一道很常见的面试题是用递归实现字符串反转,代码如下所示:
162.怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?
答:代码如下所示:
String s1 = "你好";
String s2 = newString(s1.getBytes("GB2312"), "ISO-8859-1");
163.Java中的日期和时间:
1 ) 如何取得年月日、小时分钟秒?
2 ) 如何取得从1970年1月1日0时0分0秒到现在的毫秒数?
3 ) 如何取得某月的最后一天?
4 ) 如何格式化日期?
答:操作方法如下所示:
1 ) 创建java.util.Calendar 实例,调用其get()方法传入不同的参数即可获得参数所对应的值
2 ) 以下方法均可获得该毫秒数:
Calendar.getInstance().getTimeInMillis();
time.getActualMaximum(Calendar.DAY_OF_MONTH);
4 ) 利用java.text.DataFormat 的子类(如SimpleDateFormat类)中的format(Date)方法可将日期格式化。
164.打印昨天的当前时刻。
165.Java反射技术主要实现类有哪些,作用分别是什么?
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中
1)Class类:代表一个类
2)Field 类:代表类的成员变量(属性)
3)Method类:代表类的成员方法
4)Constructor 类:代表类的构造方法
5)Array类:提供了动态创建数组,以及访问数组的元素的静态方法
166.Class类的作用?生成Class对象的方法有哪些?
Class类是Java 反射机制的起源和入口,用于获取与类相关的各种信息,提供了获取类信息的相关方法。Class类继承自Object类
Class类是所有类的共同的图纸。每个类有自己的对象,好比图纸和实物的关系;每个类也可看做是一个对象,有共同的图纸Class,存放类的 结构信息,能够通过相应方法取出相应信息:类的名字、属性、方法、构造方法、父类和接口
示 例
对象名
.getClass()
String str="bdqn";
Class clazz = str.getClass();
对象名
.getSuperClass()
Student stu = new Student();
Class c1 = stu.getClass();
Class c2 = stu.getSuperClass();
Class.forName()
Class clazz = Class.forName("java.lang.Object");
Class.forName("oracle.jdbc.driver.OracleDriver");
类名.class
类名.class
Class c2 = Student.class;
Class c2 = int.class
包装类.TYPE
包装类.TYPE
Class c2 = Boolean.TYPE;
167.反射的使用场合和作用、及其优缺点
1)使用场合
在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息。
2)主要作用
通过反射可以使程序代码访问装载到JVM 中的类的内部信息,获取已装载类的属性信息,获取已装载类的方法,获取已装载类的构造方法信息
3)反射的优点
反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;反射是其它一些常用语言,如C、C++、Fortran 或者Pascal等都不具备的
4) Java反射技术应用领域很广,如软件测试等;许多流行的开源框架例如Struts、Hibernate、Spring在实现过程中都采用了该技术
5)反射的缺点
性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此Java反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
使用反射会模糊程序内部逻辑:程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。
168.面向对象设计原则有哪些
面向对象设计原则是面向对象设计的基石,面向对象设计质量的依据和保障,设计模式是面向对象设计原则的经典应用
1)单一职责原则SRP
2)开闭原则OCP
3)里氏替代原则LSP
4)依赖注入原则DIP
5)接口分离原则ISP
6)迪米特原则LOD
7)组合/聚合复用原则CARP
8)开闭原则具有理想主义的色彩,它是面向对象设计的终极目标。其他设计原则都可以看作是开闭原则的实现手段或方法
String相关:
169.下面程序的运行结果是()(选择一项)
A.true
B.false
C.hello
D.he
答案:B
分析:str1没有使用new关键字,在堆中没有开辟空间,其值”hello”在常量池中,str2使用new关键字创建了一个对象,在堆中开辟了空间,”==”比较的是对象的引用,即内存地址,所以str1与str2两个对象的内存地址是不相同的
170.Java语言中,String类中的indexOf()方法返回值的类型是()
A.int16
B.int32
http://C.int
D.long
答案:C
171.给定以下代码,程序的运行结果是 ()(选择一项)
A.goodandabcB.goodandgbcC.test okandabcD.test okandgbc
答案:B
分析:在方法调用时,在change方法中对str的值进行修改,是将str指向了常量江池中的”test ok”,而主方法中的ex.str仍然指向的是常量池中的”good”。字符型数组在方法调用时,将主方法中ex.ch的引用传递给change方法中的ch,指向是堆中的同一堆空间,所以修改ch[0]的时候,ex.ch可以看到相同的修改后的结果。
172.执行下列代码后,哪个结论是正确的()(选择两项)
A.s[10]为””
B.s[9]为null
C.s[0]为未定义
D.s.length为10
答案:BD
分析: 引用数据类型的默认值均为null
s.length数组的长度
173.实现String类的replaceAll方法
思路说明:replaceAll方法的本质是使用正则表达式进行匹配,最终调用的其实是Matcher对象的replaceAll方法。
174.在“=”后填写适当的内容:
String []a=new String[10];
则:a[0]~a[9]=null;
a.length=10;
如果是int[]a=new int[10];
则:a[0]~a[9]= (0)
a.length= (10)
175.是否可以继承String类?
答:不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。
public final class String implements java.io.Serializable,
Comparable< String>, CharSequence
176.给定两个字符串s和t, 写一个函数来决定是否t是s的重组词。你可以假设字符串只包含小写字母。
177.String s=new String(“abc”);创建了几个String对象。
两个或一个,”abc”对应一个对象,这个对象放在字符串常量缓冲区,常量”abc”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它一句那个常量”abc”对象的内容来创建出一个新String对象。如果以前就用过’abc’,这句代表就不会创建”abc”自己了,直接从缓冲区拿。
178.输出结果?
179.下列程序的输出结果是什么?
0 Hello world
1 Hello world
2 Hello world
3 Hello world
4 Hello world
5 Hello world
6 Hello world
7 Hello world
8 Hello world
9 Hello world
180.关于java.lang.String类,以下描述正确的一项是()
A.String类是final类故不可继承
B.String类final类故可以继承
C.String类不是final类故不可继承
D.String;类不是final类故可以继承
答案:A
181.下面哪个是正确的()
A.String temp[ ] = new String{“a”,”b”,”c”};
B.String temp[ ] = {“a”,”b”,”c”};
C.String temp= {“a”,”b”,”c”};
D.String[ ] temp = {“a”,”b”,”c”};
答案:BD
182.已知如下代码:执行结果是什么()
A.false true true
B.true false true
C.true true false
D.true true false
答案:A
183.字符串如何转换为int类型
184.写一个方法,实现字符串的反转,如:输入abc,输出cba
185.编写java,将“I follow Bill Gate.Tom Gate.John Gate”中的“Gate”全部替换为“Gates”
186.String 是最基本的数据类型吗?
答: 不是 。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type)和枚举类型(enumeration type),剩下的都是引用类型(reference type)。
187.String 和StringBuilder、StringBuffer 的区别?
答: Java 平台提供了两种类型的字符串:String和StringBuffer / StringBuilder
相同点:
它们都可以储存和操作字符串,同时三者都使用final修饰,都属于终结类不能派生子类,操作的相关方法也类似例如获取字符串长度等;
不同点:
其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的,而StringBuffer和StringBuilder类表示的字符串对象可以直接进行修改,在修改的同时地址值不会发生改变。StringBuilder是JDK 1.5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer略高。在此重点说明一下,String、StringBuffer、StringBuilder三者类型不一样,无法使用equals()方法比较其字符串内容是否一样!
补充1:有一个面试题问:有没有哪种情况用+做字符串连接比调用StringBuffer / StringBuilder对象的append方法性能更好?如果连接后得到的字符串在静态存储区中是早已存在的,那么用+做字符串连接是优于StringBuffer / StringBuilder的append方法的。
解析:
String类存在intern()方法,含义如下:返回字符串对象的规范化表示形式。它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
字符串比较分为两种形式,一种使用比较运算符”==”比较,他们比较的是各自的字符串在内存当中的地址值是否相同;一种是使用equals()方法进行比较,比较的是两个字符串的内容是否相同!
结果如下:
a == b-->false
a == c-->true
a.equals(b)-->true
a.equals(c)-->true
a.intern() == b.intern()-->true
188.String类为什么是final的
答:1) 为了效率。若允许被继承,则其高度的被使用率可能会降低程序的性能。
2)为了安全。JDK中提供的好多核心类比如String,这类的类的内部好多方法的实现都不是java编程语言本身编写的,好多方法都是调用的操作系统本地的API,这就是著名的“本地方法调用”,也只有这样才能做事,这种类是非常底层的,和操作系统交流频繁的,那么如果这种类可以被继承的话,如果我们再把它的方法重写了,往操作系统内部写入一段具有恶意攻击性质的代码什么的,这不就成了核心病毒了么?不希望别人改,这个类就像一个工具一样,类的提供者给我们提供了, 就希望我们直接用就完了,不想让我们随便能改,其实说白了还是安全性,如果随便能改了,那么java编写的程序肯定就很不稳定,你可以保证自己不乱改, 但是将来一个项目好多人来做,管不了别人,再说有时候万一疏忽了呢?他也不是估计的, 所以这个安全性是很重要的,java和C++相比,优点之一就包括这一点。
189.String类型是基本数据类型吗?基本数据类型有哪些
1) 基本数据类型包括byte、short/char、int、long、float、double、boolean
2 ) java.lang.String类是引用数据类型,并且是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类
190.String s="Hello";s=s+"world!";执行后,是否是对前面s指向空间内容的修改?
答:不是对前面s指向空间内容的直接修改。
因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。
通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:
而非
s = new String("Initial Value");
后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。
上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。
至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。
191.String s = new String("xyz");创建几个String Object?
答:两个或一个,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它一句那个常量”xyz”对象的内容来创建出一个新String对象。如果以前就用过’xyz’,这句代表就不会创建”xyz”自己了,直接从缓冲区拿。
192.下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d";
答:对于如下代码:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。
题目中的第一行代码被编译器在编译时优化后,相当于直接定义一个”abcd”的字符串,所以,上面的代码应该只创建了一个String对象。
写如下两行代码,
String s = "a" + "b" + "c" + "d";
System.out.println(s == "abcd");
最终打印的结果应该为true。
193.Java集合体系结构(List、Set、Collection、Map的区别和联系)
1、Collection 接口存储一组不唯一,无序的对象
2、List 接口存储一组不唯一,有序(插入顺序)的对象
3、Set 接口存储一组唯一,无序的对象
4、Map接口存储一组键值对象,提供key到value的映射。Key无序,唯一。value不要求有序,允许重复。(如果只使用key存储,而不使用value,那就是Set)
194.Vector和ArrayList的区别和联系
相同点:
1)实现原理相同---底层都使用数组
2)功能相同---实现增删改查等操作的方法相似
3)都是长度可变的数组结构,很多情况下可以互用
不同点:
1)Vector是早期JDK版本提供,ArrayList是新版本替代Vector的
2)Vector线程安全,ArrayList重速度轻安全,线程非安全长度需增长时,Vector默认增长一倍,ArrayList增长50%
195.ArrayList和LinkedList的区别和联系
相同点:
两者都实现了List接口,都具有List中元素有序、不唯一的特点。
不同点:
ArrayList实现了长度可变的数组,在内存中分配连续空间。遍历元素和随机访问元素的效率比较高;
LinkedList采用链表存储方式。插入、删除元素时效率比较高
196.HashMap和Hashtable的区别和联系
相同点:
实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用
不同点:
1、Hashtable是早期提供的接口,HashMap是新版JDK提供的接口
2、Hashtable继承Dictionary类,HashMap实现Map接口
3、Hashtable线程安全,HashMap线程非安全
4、Hashtable不允许null值,HashMap允许null值
197.HashSet的使用和原理(hashCode()和equals())
1)哈希表的查询速度特别快,时间复杂度为O(1)。
2)HashMap、Hashtable、HashSet这些集合采用的是哈希表结构,需要用到hashCode哈希码,hashCode是一个整数值。
3)系统类已经覆盖了hashCode方法 自定义类如果要放入hash类集合,必须重写hashcode。如果不重写,调用的是Object的hashcode,而Object的hashCode实际上是地址。
4)向哈希表中添加数据的原理:当向集合Set中增加对象时,首先集合计算要增加对象的hashCode码,根据该值来得到一个位置用来存放当前对象,如在该位置没有一个对象存在的话,那么集合Set认为该对象在集合中不存在,直接增加进去。如果在该位置有一个对象存在的话,接着将准备增加到集合中的对象与该位置上的对象进行equals方法比较,如果该equals方法返回false,那么集合认为集合中不存在该对象,在进行一次散列,将该对象放到散列后计算出的新地址里。如果equals方法返回true,那么集合认为集合中已经存在该对象了,不会再将该对象增加到集合中了。
5)在哈希表中判断两个元素是否重复要使用到hashCode()和equals()。hashCode决定数据在表中的存储位置,而equals判断是否存在相同数据。
6) Y=K(X) :K是函数,X是哈希码,Y是地址
198.TreeSet的原理和使用(Comparable和comparator)
1)TreeSet集合,元素不允许重复且有序(自然顺序)
2)TreeSet采用树结构存储数据,存入元素时需要和树中元素进行对比,需要指定比较策略。
3)可以通过Comparable(外部比较器)和Comparator(内部比较器)来指定比较策略,实现了Comparable的系统类可以顺利存入TreeSet。自定义类可以实现Comparable接口来指定比较策略。
4)可创建Comparator接口实现类来指定比较策略,并通过TreeSet构造方法参数传入。这种方式尤其对系统类非常适用。
199.集合和数组的比较(为什么引入集合)
数组不是面向对象的,存在明显的缺陷,集合完全弥补了数组的一些缺点,比数组更灵活更实用,可大大提高软件的开发效率而且不同的集合框架类可适用于不同场合。具体如下:
1)数组的效率高于集合类.
2)数组能存放基本数据类型和对象,而集合类中只能放对象。
3)数组容量固定且无法动态改变,集合类容量动态改变。
4)数组无法判断其中实际存有多少元素,length只告诉了array的容量。
5)集合有多种实现方式和不同的适用场合,而不像数组仅采用顺序表方式。
6)集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性调用即可实现各种复杂操作,大大提高软件的开发效率。
200.Collection和Collections的区别
1)Collection是Java提供的集合接口,存储一组不唯一,无序的对象。它有两个子接口List和Set。
2)Java中还有一个Collections类,专门用来操作集合类 ,它提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
201.下列说法正确的有()(选择一项)
A.LinkedList继承自List
B.AbstractSet继承自Set
C.HashSet继承自AbstractSet
D.TreeMap继承自HashMap
答案: C
分析:A:LinkedList实现List接口
B:AbstractSet实现Set接口
D:TreeMap继承AbstractMap
202.Java的HashMap和Hashtable有什么区别HashSet和HashMap有什么区别?使用这些结构保存的数需要重载的方法是哪些?
答:HashMap与Hashtable实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用
两者的主要区别如下
1、Hashtable是早期JDK提供的接口,HashMap是新版JDK提供的接口
2、Hashtable继承Dictionary类,HashMap实现Map接口
3、Hashtable线程安全,HashMap线程非安全
4、Hashtable不允许null值,HashMap允许null值
HashSet与HashMap的区别
1、HashSet底层是采用HashMap实现的。HashSet 的实现比较简单,HashSet 的绝大部分方法都是通过调用 HashMap 的方法来实现的,因此 HashSet 和 HashMap 两个集合在实现本质上是相同的。
2、HashMap的key就是放进HashSet中对象,value是Object类型的。
3、当调用HashSet的add方法时,实际上是向HashMap中增加了一行(key-value对),该行的key就是向HashSet增加的那个对象,该行的value就是一个Object类型的常量
203.列出Java中的集合类层次结构?
答:Java中集合主要分为两种:Collection和Map。Collection是List和Set接口的父接口;ArrayList和LinkedList是List的实现类;HashSet和TreeSet是Set的实现类;LinkedHashSet是HashSet的子类。HashMap和TreeMap是Map的实现类;LinkedHashMap是HashMap的子类。
图中:虚线框中为接口,实线框中为类。
204.List,Set,Map各有什么特点
答:List 接口存储一组不唯一,有序(插入顺序)的对象。
Set 接口存储一组唯一,无序的对象。
Map接口存储一组键值对象,提供key到value的映射。key无序,唯一。value不要求有序,允许重复。(如果只使用key存储,而不使用value,那就是Set)。
205.ArrayList list=new ArrayList(20);中的list扩充几次()
A.0
B.1
C.2
D.3
答案:A
分析:已经指定了长度, 所以不扩容
206.List、Set、Map哪个继承自Collection接口,一下说法正确的是()
A.List Map
B.Set Map
C.List Set
D.List Map Set
答案:C
分析:Map接口继承了java.lang.Object类,但没有实现任何接口.
207.合并两个有序的链表
208.用递归方式实现链表的转置。
209.给定一个不包含相同元素的整数集合,nums,返回所有可能的子集集合。解答中集合不能包含重复的子集。
210.以下结构中,哪个具有同步功能()
A.HashMap
B.ConcurrentHashMap
C.WeakHashMap
D.TreeMap
答案:B
分析:
A,C,D都线程不安全,B线程安全,具有同步功能
211.以下结构中,插入性能最高的是()
A.ArrayList
B.Linkedlist
C.tor
D.Collection
答案:B
分析:
数组插入、删除效率差,排除A
tor不是java里面的数据结构,是一种网络路由技术;因此排除C
Collection 是集合的接口,不是某种数据结构;因此排除D
212.以下结构中,哪个最适合当作stack使用()
A.LinkedHashMap
B.LinkedHashSet
C.LinkedList
答案:C
分析:
Stack是先进后出的线性结构;所以链表比较合适;不需要散列表的数据结构
213.Map的实现类中,哪些是有序的,哪些是无序的,有序的是如何保证其有序性,你觉得哪个有序性性能更高,你有没有更好或者更高效的实现方式?
答:1. Map的实现类有HashMap,LinkedHashMap,TreeMap
2. HashMap是有无序的,LinkedHashMap和TreeMap都是有序的(LinkedHashMap记录了添加数据的顺序;TreeMap默认是自然升序)
3. LinkedHashMap底层存储结构是哈希表+链表,链表记录了添加数据的顺序
4. TreeMap底层存储结构是二叉树,二叉树的中序遍历保证了数据的有序性
5. LinkedHashMap有序性能比较高,因为底层数据存储结构采用的哈希表
214.下面的代码在绝大部分时间内都运行得很正常,请问什么情况下会出现问题?根源在哪里?
答:将if( list.size() <= 0 )改成:while( list.size() <= 0 )
215.TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
答:TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会 回调该方法比较元素的大小。TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序。Collections 工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是是通过接口注入比较元素大小的算法,也是对回调模式的应用。
216.List里面如何剔除相同的对象?请简单用代码实现一种方法
217.Java.util.Map的实现类有
分析:Java中的java.util.Map的实现类
1、HashMap
2、Hashtable
3、LinkedHashMap
4、TreeMap
218.下列叙述中正确的是()
A.循环队列有队头和队尾两个指针,因此,循环队列是非线性结构
B.在循环队列中,只需要队头指针就能反映队列中元素的动态变化情况
C.在循环队列中,只需要队尾指针就能反映队列中元素的动态变化情况
D.在循环队列中元素的个数是由队头指针和队尾指针共同决定的
答案:D
分析:循环队列中元素的个数是由队首指针和队尾指针共同决定的,元素的动态变化也是通过队首指针和队尾指针来反映的,当队首等于队尾时,队列为空。
219.List、Set、Map 是否继承自Collection 接口?
答:List、Set 的父接口是Collection,Map 不是其子接口,而是与Collection接口是平行关系,互不包含。
Map是键值对映射容器,与List和Set有明显的区别,而Set存储的零散的元素且不允许有重复元素(数学中的集合也是如此),List是线性结构的容器,适用于按数值索引访问元素的情形。
220.说出ArrayList、Vector、LinkedList 的存储性能和特性?
答:ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized 方法(线程安全),通常性能上较ArrayList 差,而LinkedList 使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,其实对内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。Vector属于遗留容器(早期的JDK中使用的容器,除此之外Hashtable、Dictionary、BitSet、Stack、Properties都是遗留容器),现在已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的,如果需要多个线程操作同一个容器,那么可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这其实是装潢模式最好的例子,将已有对象传入另一个类的构造器中创建新的对象来增加新功能)。
补充:遗留容器中的Properties类和Stack类在设计上有严重的问题,Properties是一个键和值都是字符串的特殊的键值对映射,在设计上应该是关联一个Hashtable并将其两个泛型参数设置为String类型,但是Java API中的Properties直接继承了Hashtable,这很明显是对继承的滥用。这里复用代码的方式应该是HAS-A关系而不是IS-A关系,另一方面容器都属于工具类,继承工具类本身就是一个错误的做法,使用工具类最好的方式是HAS-A关系(关联)或USE-A关系(依赖) 。同理,Stack类继承Vector也是不正确的。
由于字数限制,后续内容更加精彩,欢迎关注,整理不易,可否动动你的小手给小编来点更新的动力,希望对你们会有帮助!~