31. float和double型的取值范围
实型又称浮点型,用来表示带小数部分的实型数据。
浮点数的存储格式:符号位、指数位、尾数位。
float 4个字节,范围从3.4E(-38)3.4E38。一个浮点数由2部分组成:底数m 和 指数e。±mantissa × 2^exponent。注意,公式中的mantissa 和 exponent使用二进制表示。指数部分占8 bit,由于有符号,所以指数部分的范围为-128128,而-2^(-128)2^128约等于3.4E(-38)3.4E38。精度(有效数字)看尾数部分。float类型一般在数字后面加f或F。
double 8个字节,范围从1.7E(-138)~1.7E138。
32. 利用BigDecimal类进行精确计算
通常float或double只能用于科学计算,在大多数商业计算中,需要用java.math.BigDecimal类。
使用BigDecimal类来进行计算的步骤:
(1)用BigDecimal的构造器把基本类型或其String类型转换成BigDecimal对象;用静态valueOf()方法把基本类型变量构建成BigDecimal对象;
(2)调用BigDecimal的加减乘除进行运算;
(3)将BigDecimal对象通过 Value()方法转换成float、double、int等类型。
1 | double val = 1.0; |
33. boolean类型和Boolean类型的区别
对于C/C++,用0代表false,非0代表true。而Java的boolean类型只能用true或false来代表真假(所以if(100)这种是不能执行的,if(100>90)可以执行)。
其包装类Boolean类型通常有三种状态:true、false、null,初始化时通常初始化为false。
boolean型由于是基本数据类型,通常存放在栈空间;而Boolean类型对象存放在堆空间。
34. char的取值范围
char采用Unicode编码,每个字符占2个字节,则取值范围02^16-1。Unicode兼容ASCII码,英文字母0127。
1 | char z = ‘中’; |
35. 字符串字面量是否生成一个新的String对象
String str1 = “abc”; //JVM到String对象池中去搜索该字符串是否已经被创建,若创建则返回该对象的引用,否则先创建该字符串,再返回引用。
String str2 = new String(“abc”); //与str1的创建过程相同,还创建了一个新的String对象(即new关键字的作 用),并返回一个引用给str2。
36. 字符串对象池
JVM在启动时会实例化9个对象池,包括8个基本类型对应的包装类和String对象,主要是为了避免频繁地创建和销毁对象影响系统性能。
37. StringBuffer和StringBuilder
String具有不变性,它只能被创建,不能被改变。
StringBuilder不是线程安全的,它适用于单线程环境,例如SQL 语句的拼装、JSON封装等;
StringBuffer是线程安全的,它适用多线程环境,如XML解、HTTP参数解析和封装等。
38. 如何输出反转后的字符串
StringBuffer的reverse()方法。
1 | String s = “ab”; |
39. 如何使用指定字符集创建String对象
使用String类的带参构造器即可,参数包括两个:一个是指定字符集的byte数组,一个是字符集编码的字符串形式。
1 | String a= “中文”; |
40. 理解数组在Java中是一个类
Java中只有8种基本数据类型,其它都是引用数据类型。
获取数组的类名:arr.getClass().getName();
数组的类名总是以“[”开头,后面跟的标示不同:int型是一个I字符;字符串类型是Ljava.lang.String。
41. 引用类型数组
引用类型数组中存放的是数据的引用。
1 | Object[] obj = new Object[3]; |
42. 如何拷贝数组的数据
由于引用类型数组中存的是数据的引用,因此不能直接对数组的内容进行复制。使用System.arrayCopy((Object src, int srcPos, Object dest, int destPos, int length))。
其中
src - the source array.
srcPos - starting position in the source array.
dest - the destination array.
destPos - starting position in the destination data.
length - the number of array elements to be copied.
43. 二维数组
Java的二维数组是这样的:先创建一个一维数组,然后该数组的元素再引用另外一个一维数组。
44. 集合类
集合类只能存放对象,因此基础数据类型需要自动装箱成包装类才能存放。
1) Set:无序、不可重复的集合。HashSet, TreeSet
2) List:有序、可重复的集合。ArrayList, LinkedList, Vector
3) Queue:队列集合。ArrayDeque, LinkedList, Deque(ArrayDeque)
4) Map:具有映射关系的集合。HashMap, TreeMap, HashTable
45. 迭代器(Iterator,Cursor游标)
Java提供Iterable和Iterator接口来遍历集合元素。迭代器提供一种访问集合对象中各个元素的途径,同时又不需要暴露该对象的内部细节。
与使用Iterator接口遍历集合元素类似的是,使用foreach循环的迭代变量也不是集合对象本身,而是集合对象的内部的元素值。因此为了避免共享资源引发的潜在问题,不能修改集合对象的元素值,否则会引发ConcurrentModificationException异常。
迭代器的主要用法是,用hasNext()作为循环条件,再用next()方法得到下一个元素,最后再进行相关操作。
46. 比较器(Comparator)
比较器指的是集合存储的元素的特性。比较器用于比较自定义类的实例之间的大小。
Java提供Comparable和Comparator接口来比较集合元素。
比较器是把集合元素和数组强行按照指定的方式进行排序的对象,它是实现了Comparator接口的实例。如果一个集合元素是可比较的(实现了Comparable接口),则它就拥有了默认的排序方法,比较器则是强行改变它的默认比较方式来排序;如果集合元素不可比较(没有实现Comparable接口),则可通过实现Comparator接口来实现动态排序。
1) Comparable接口
进行比较的类先实现Comparable接口,然后重写其int compareTo(..)方法,一个参数,返回值大于0则表示本对象大于参数对象。Comparable接口也可单独成类。
1 | public class ComparableUser implements Comparable{ |
2)Comparator接口
Comparator接口一般不被集合元素所实现,而是单独实现(单独一个类)或用匿名内部类的方式。它包含一个int compare()方法,两个参数,返回值与Comparable接口一样。
1 | public class User{ |
1 | /**单独一个实现类实现Comparator接口**/ |
47. ArrayList(线程不安全)和Vector(线程安全)的区别
ArrayList和Vector都是List接口的实现类,它们都代表链表形式的数据结构,且它们的实现方式非常类似,都是用一个对象数组来存储元素。
1) Vector大多数成员方法是使用synchronized关键字修饰的,也就是线程安全的;
2) 因此若不要求同步,ArrayList不是线程安全的,它的效率更高。
add()添加、remove()删除、size()得到集合元素数量。
48. HashMap(线程不安全)和HashTable(线程安全)的区别
HashMap和HashTable都是Map接口的实现类,保存元素时都是无序的。
1) HashTable不允许key或value为null,它的方法是同步的,是线程安全的,使用Enumeration遍历,有一个contains()方法,功能和containsValue()方法一样,直接使用对象的hashCode();
2) 而HashMap允许key或value为null,它的方法不同步,是线程不安全的,使用Iterator遍历,需要重新计算hash值。
1 | //通过key集合遍历集合value |
49. 集合使用泛型的好处
集合可以存放任何类型的元素,如果在存放元素之前,就能确定元素的类型,将会使代码更加简洁,避免手动进行类型转换。而常常我们并不确定最终我们要放进集合的数据类型,所以用一种通用的方式进行定义,而不必写出具体的类,这些未知的类会在真正使用的时候再确定。
50. 对集合对象中的元素进行排序(针对List集合)
集合框架中的List的实现有ArrayList、Vector、LinkedList,这些集合是没有排序功能的,我们使用java.util.Collections类中的sort()方法进行排序。若这个类实现了Comparable接口,则直接调用Colletions.sort()方法;如果这个类没有实现Comparator,就可以传递一个Comparator实例作为sort()的第二个参数进行排序。
51. 符合什么条件可以使用foreach循环
foreach起到替代迭代器的作用,从语法上来讲,数组或实现了Iterable接口的类实例,都可以使用foreach循环。
可以自定义集合类,实现Iterable和Iterator接口。如
1 | public class MyForeach{ |
1 | class MyList implements Iterable<String>,Iterator<String>{ |
52. JFrame的作用
Java关于图形界面的开发有两套API,一个是AWT,一个是Swing。但AWT已慢慢退出历史舞台,大多数时候的Java图形界面开发指的就是Swing开发。
JFrame起到了Swing窗口的作用,其它一切的组件都在它的包含之内。
窗口中添加的内包括:按钮(Button)、文本框(Text)、滚动条(Scroll Bar)、标签(Label)等。
1 | import javax.swing.JFrame; |
53. 创建按钮(JButton)
1 | // 添加按钮前必须先设置布局格式,否则JFrame中无法加入JButton |
54. 使用文本输入组件(JTextField和JTextArea)
1)JTextField(文本框):只能单行输入;
1 | jf.setLayout(new FlowLayout()); |
2)JTextArea(文本域):允许多行输入。
1 | JTextArea jta = new JTextArea(5, 10); //与JTextField不同之处就是文本域需要提供长和宽 |
55. 如何捕获事件
事件:一个对象A的状态改变了的时候,通知其他对象发生了这样一件事,让他做出反应。
两种事件模式,即推/拉模式。推模式:对象A状态改变了,通知其他对象做出反应,Java的大多数事件模式都属于这一种;拉模式:其他对象监听感兴趣的对象A(如WIN32的图形用户界面编程)。
一次事件模型中,往往有3中角色:
(1) 事件发生的主体:状态随用户操作而改变,如按钮;
(2) 监听器:实现了某种或某些监听接口的类实例,如监听按钮的监听器;
(3) 事件:代表一种动作,通过它获取用户操作的信息,如按钮被单击。
一般通过以下步骤来获取事件模型:
(1) 创建组件对象,如JButton;
(2) 创建实现了监听器接口或继承自某个适配器类的实现类,该监听器必须实现一个***Listener接口;
(3) 调用组件对象的add***Listener()方法,为该组件添加监听器。
1 | public class HelloEvent{ |
56. 使用BorderLayout布局
AWT提供了5种常用的布局管理器: BorderLayout、FlowLayout、GridLayout、GridBagLayout 、GardLayout;Swing还提供了1种:BoxLayout。
BorderLayout是Swing容器的默认布局管理器。BorderLayout把容器分为东南西北中5个部分,在JFrame中放置组件的时候,参数中多添加一项,指明组件的方位.
1 | jf.add(new JButton(“north”), BorderLayout.NORTH)); |
57. 使用FlowLayout布局
FlowLayout是将组件从左往右、从上到下排列。
1 | jf.setLayout(new FlowLayout()); |
58. 使用GrideLayout布局
GridLayout是一种表格式的布局管理器,从左到右从上到下摆放组件,而且它会填满整个容器。创建GridLayout时指定行数和列数。
1 | jf.setLayout(new GridLayout(10, 10)); |
59. 事件模型的通用规则
1) 所有的Swing组件都有add***Listener()和remove***Listener()方法,用于注册和取消注册事件监听器,***代表事件的类型和含义;
2) ***事件的监听器类型叫***Listener,它们是add***Listener()和remove***Listener()方法的参数类型;
3) ***事件的类名叫***Event,它常作为***Listener接口的方法参数。
1 | bt.addActionListener(new ActionListener(){ |
60. 监听器的适配器(adapter)的作用
为一个组件添加监听器就是加入一个监听器接口的类实例,调用add***Listener()方法即可。但是如果这个方法的接口太多,而我们只需要使用其中一些方法,这就比较浪费。适配器为一些监听器接口的方法提供默认的空实现,减少代码冗余。
1 | jtf.addKeyListener(new KeyAdapter(){ |
适配器是一个类,如果事件处理类已经继承自其它接口,就不能继承自适配器类了。也可以自定义适配器。