一、如何产生一个随机数?
需要使用java.lang包中的Math类,Math类有一个产生随机数的方法是:random();
例如:
int i = (int)(Math.random()*4);
Math.random()返回的是大于等于0小于1的随机数,带正号的double值。如果乘以一个正整数,则会返回0——正整数之间的随机数,而并不包括这个正整数,是为什么呢?
就是因为这个方法返回的是0-1之间的随机数,随机数不会返回1,因此乘上一个整数还是只会返回0——这个整数之间的随机值。
二、Math类的常用方法
package com.changyongclass;
public class MathTest {
public static void main(String[] args) {
int i = -123;
//绝对值
System.out.println(Math.abs(i));
//正平方根
System.out.println(Math.sqrt(3.33));
//多少次幂
System.out.println(Math.pow(2d, 3));
//两数较大者
System.out.println(Math.max(3d, 2d));
//两数较小者
System.out.println(Math.min(3d, 5d));
//double转long
System.out.println(Math.round(5.555555d));
}
}
三、基本数据类型的包装类
1、为什么需要给基本数据类型提供包装类?
因为Java语言中“一切皆对象”,但是基本数据类型有些违背这个原则。对象有方法,有属性,基本数据类型没有啊。
所以为了体现面向对象的思想,就为每一个基本类型提供了包装类,包装类提供了很多方法,可以简化程序的编写。
2、使用基本数据类型与使用封装类型有些什么不同呢?
基本数据类型的特点是存储范围较小,但在程序中会大量的使用。我们知道new出来的对象是在堆中创建的,但在堆中分配内存的效率要远低于栈空间,因此,Java对于这些小的简单的变量给予特殊的对待,即,将其放在栈空间,这样就会更加高效。
3、基本数据类型与包装类的对应关系是怎样的?
boolean-----------------Boolean
byte----------------------Byte
short---------------------Short
char----------------------Character
int------------------------Integer
long----------------------Long
float----------------------Foat
Double-------------------Double
4、java SE5的规范中实现了基本类型与包装类的自动拆装箱
例:
Character ch = 'x';//自动装箱
char c = ch; //自动拆箱
五、Enum枚举类
1、为什么要使用枚举?
有些时候我们想让变量的取值在一个有限的集合内,如果变量的值没有限定在有限的集合内,就有可能在变量中保存一个错误的值。
2、下面是我对枚举类知识点的总结:
packagecom.lesson5;
importjava.util.ArrayList;
importjava.util.List;
publicclassCard {
/**
*定义在类里面的枚举,相当于java里面的类部类一样
*/
/**
* DEUCE...相当于Rank类的一个实例
*
*1、枚举生成类的实例的方式与生成普通类的实例的方式有些区别
*也就是说,放在枚举类型里面的变量,它们都是我们枚举类型
*里面的实例
*
* 2、如果不对一个普通类做限制可以生成任意多个实例,对于枚举
*来说,在定义枚举的时候已经定义好了,也就是说,枚举的实例
*数量是有限的
*/
publicenumRank{
DEUCE,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN,JACK,QUEEN,KING,ACE;
}
publicenumSuit{
CLUBS,DIAMONDS,HEARTS,SPADES
}
/**
*定义枚举类型的变量
*/
privatefinalRankrank;
privatefinalSuitsuit;
/**
*定义构造方法对Rank与suit赋值,初始化
*此构造方法是private类型的,也就是说,我们不能在类的外面
*去使用这个类的构造方法,private的构造方法,最多的用在单
*态,也就是singleton的设计模式里面,用来保证一个类只有一
*个实例
*@paramrank
*@paramsuit
*/
privateCard(Rank rank,Suit suit){
this.rank= rank;
this.suit= suit;
}
/**
*用于返回我们定义的的的rank与suit
*@return
*/
publicRank rank(){
returnrank;
}
publicSuit suit(){
returnsuit;
}
/**
*重写toString()
* java里面所有类的顶层类都是Object的,
*/
publicString toString(){
//此处rank与suit又会调用它们的toString()方法,打印出来。
returnrank+" of "+suit;
}
privatestaticfinalListprotoDeck=newArrayList();
/**
*静态代码块
*执行的时机是在类被加载之后,执行的,它只执行一次,且仅执行一次
*它是早于构造方法去执行的,并且仅仅在类进行实例化的时候,执行一次,
*以后再实例化的时候,这个静态代码块就永远不会再去执行了。
*/
static{
for(Suit suit : Suit.values()){
for(Rank rank : Rank.values()){
protoDeck.add(newCard(rank,suit));
}
}
}
/**
*定义静态方法执行一个集合拷贝
*/
publicstaticArrayList newDeck(){
//它会将protoDeck对象的一个拷贝,构造ArrayList的时候,将之前的构造的ArrayList
//作为参数传进去了,它会直接拷进新的集合里面去,然后返回
returnnewArrayList(protoDeck);//return copy of prototype deck
}
publicstaticvoidmain(String[] args) {
for(Card card:protoDeck){
//打印card实际上是调用card.toString()方法,在这里面已经将toString()进行重写
//了
System.out.println(card);
}
}
}
packagecom.lesson5;
publicenumCoin {
/**
*定义枚举里面的元素
*/
/**
*定义枚举里面的变量,这里面的每一个都是Coin这样一个类型
*相当于它的一个实例,给它提供了一个构造方法,对于枚举来
*说,这里面跟类是一样的,对于我们不提供一个类的构造方法
*来说,jdk在编译的时候,会给它生成一个不带参数的默认构造方法
*这个构造方法什么都不做。
*
*枚举也是一样的,对于没有枚举构造方法,在编译之后,java会
*自动的给它生成一个不带参数的构造方法
*
*在此类中,我们给它提供了一个构造方法,一个带参数的构造方法,
*因此下面的相当于实例的元素,也需要带上构造方法。
*相当于之前我们做new Student(12);
*/
penny(1),nickel(5),dime(10),quarter(25);
/**
*枚举可以定义任何的变量,任何的方法,
*/
privateintvalue;
publicintgetValue() {
returnvalue;
}
/**
*枚举实际上也是一种特殊的类
*枚举也有构造方法
*@paramvalue
*/
Coin(intvalue){
this.value= value;
}
publicstaticvoidmain(String[] args) {
//用枚举的某一个实例给枚举进行赋值
Coin coin = Coin.quarter;
//赋值时,就已经将25赋给了value,再通过getValue()得到值。
System.out.println(coin.getValue());
}
}
packagecom.lesson5;
publicenumCoin2 {
penny("hello"),nickel("world"),dime("welcome"),quarter("hi");
privateStringvalue;
publicString getValue() {
returnvalue;
}
Coin2(String value){
this.value= value;
}
publicstaticvoidmain(String[] args) {
Coin2 coin = Coin2.quarter;
System.out.println(coin.getValue());
}
}
定义枚举类型的本质:
定义一个枚举的时候,本质上就是在定义一个类别,只不过很多细节,都由编译器帮着完成了,所以某些程度上,enum关键字的作用就像是class或interface.
当使用”enum”关键字来定义一个枚举类别的时候,实质上定义出来的类型继承自java.lang.Enum类型,而每个枚举的成员其实就是定义的枚举类型的一个实例(interface),他们都被预设为final,所以你无法改变他们,他们也是static成员,所以可以通过类型名称直接使用他们,最重要的是,他们都是公开的(public)。
为什么会有枚举这种类型出现,在我们开发项目的时候,对于用户的权限,我们可能这样去定义,比如一个用户有增加的权限,另外的一个用户可增加,可修改。另外一个用户,可以增、删、改。对于这此权限在程序里面是怎样标识的呢,实际上是用数字来标识的。
packagecom.lesson5;
/**
*枚举出现必然有它出现的理由
*@authorAdministrator
*枚举类型相当于public static final Color Red;
*/
publicenumColor {
Red,White,Blue;
//枚举里面不仅定义了变量,还定义了方法
//因此需要在定义变量完成之后加";",来对
//方法与变量进行分隔
publicstaticvoidmain(String[] args) {
Color myColor = Color.Red;
System.out.println(myColor);
for(Color c:Color.values()){
System.out.println(c);
}
}
//class Right{
只读
//private static final int CAN_READ = 1;
可写
//private static final int CAN_UPDATE = 2;
拥有所有权限
//private static final int ALL_CONTROL = 5;
//}
/**
*这样做会存在一个很致命的问题,这样在传递权限数值的时候,
*可以只需要满足一个数值类型就可以了,可以是100,然而在
*方法里面进行判断的时候,肯定就不对了
*@authorAdministrator
*/
//class Action{
判断用户到底有没有这个权限
//public Boolean canExecute(int right){
///**
//* some judgment做些判断
//*/
//return true;
return false
//}
//}
/**
*枚举的做法如下:
*此时,传递的参数,就只能是Right类型的数据了,只能是read,write,fullControl
*了,这样也不能传递任何其它的变量,因为这个枚举只有这三个类型的实例。这样系
*统进行权限判断的时候,就很好判断了。
*/
enumRight{
read,write,fullControl;
}
classAction{
//判断用户到底有没有这个权限
publicBoolean canExecute(Right right){
/**
* some judgment做些判断
*/
returntrue;
//return false
}
}
}
枚举的比较
packagecom.lesson5;
/**
*枚举的比较
*/
publicclassShowEnum {
publicstaticvoidmain(String[] args) {
//valueof()方法可以将指定的字符串转换为枚举类型。
enumCompareTo(OpConstant.valueOf(args[0]));
}
publicstaticvoidenumCompareTo(OpConstant constant){
System.out.println(constant);
//首先遍历时将OpConstant里面的对象实例取出来
//与传进命令行的参数TURN_LEFT进行相比
//发现它们俩处在同一个位置上,就返回equals0
//接着与TURN_RIGHT相比,命令行参数是在TURN_RIGHT的
//前面,所以返回一个-1
//依此类推,前面的就返回负数。
for(OpConstant c : OpConstant.values()){
System.out.println(constant.compareTo(c));
}
}
}