一、如何产生一个随机数?
需要使用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、下面是我对枚举类知识点的总结:
package com.lesson5;
import java.util.ArrayList;
import java.util.List;
public class Card {
/**
* 定义在类里面的枚举,相当于java里面的类部类一样
*/
/**
* DEUCE...相当于Rank类的一个实例
*
*1、 枚举生成类的实例的方式与生成普通类的实例的方式有些区别
* 也就是说,放在枚举类型里面的变量,它们都是我们枚举类型
* 里面的实例
*
* 2、如果不对一个普通类做限制可以生成任意多个实例, 对于枚举
* 来说,在定义枚举的时候已经定义好了,也就是说,枚举的实例
* 数量是有限的
*/
public enum Rank{
DEUCE,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN,JACK,QUEEN,KING,ACE;
}
public enum Suit{
CLUBS,DIAMONDS,HEARTS,SPADES
}
/**
* 定义枚举类型的变量
*/
private final Rank rank;
private final Suit suit;
/**
* 定义构造方法 对Rank与suit赋值 ,初始化
* 此构造方法是private类型的,也就是说,我们不能在类的外面
* 去使用这个类的构造方法,private的构造方法,最多的用在单
* 态,也就是singleton的设计模式里面,用来保证一个类只有一
* 个实例
* @param rank
* @param suit
*/
private Card(Rank rank,Suit suit){
this.rank = rank;
this.suit = suit;
}
/**
* 用于返回我们定义的的的rank与suit
* @return
*/
public Rank rank(){
return rank;
}
public Suit suit(){
return suit;
}
/**
* 重写toString()
* java里面所有类的顶层类都是Object的,
*/
public String toString(){
//此处rank 与 suit又会调用它们的toString()方法,打印出来。
return rank + " of " + suit;
}
private static final List<Card> protoDeck = new ArrayList<Card>();
/**
* 静态代码块
* 执行的时机是在类被加载之后,执行的,它只执行一次,且仅执行一次
* 它是早于构造方法去执行的,并且仅仅在类进行实例化的时候,执行一次,
* 以后再实例化的时候,这个静态代码块就永远不会再去执行了。
*/
static {
for(Suit suit : Suit.values()){
for(Rank rank : Rank.values()){
protoDeck.add(new Card(rank,suit));
}
}
}
/**
* 定义静态方法 执行一个集合拷贝
*/
public static ArrayList<Card> newDeck(){
//它会将protoDeck对象的一个拷贝,构造ArrayList的时候,将之前的构造的ArrayList
//作为参数传进去了,它会直接拷进新的集合里面去,然后返回
return new ArrayList<Card>(protoDeck);//return copy of prototype deck
}
public static void main(String[] args) {
for(Card card:protoDeck){
//打印card实际上是调用card.toString()方法,在这里面已经将toString()进行重写
//了
System.out.println(card);
}
}
}
package com.lesson5;
public enum Coin {
/**
* 定义枚举里面的元素
*/
/**
* 定义枚举里面的变量,这里面的每一个都是Coin这样一个类型
* 相当于它的一个实例,给它提供了一个构造方法,对于枚举来
* 说,这里面跟类是一样的,对于我们不提供一个类的构造方法
* 来说,jdk在编译的时候,会给它生成一个不带参数的默认构造方法
* 这个构造方法什么都不做。
*
* 枚举也是一样的,对于没有枚举构造方法,在编译之后,java会
* 自动的给它生成一个不带参数的构造方法
*
* 在此类中,我们给它提供了一个构造方法,一个带参数的构造方法,
* 因此下面的相当于实例的元素,也需要带上构造方法。
* 相当于之前我们做new Student(12);
*/
penny(1),nickel(5),dime(10),quarter(25);
/**
* 枚举可以定义任何的变量,任何的方法,
*/
private int value;
public int getValue() {
return value;
}
/**
* 枚举实际上也是一种特殊的类
* 枚举也有构造方法
* @param value
*/
Coin(int value){
this.value = value;
}
public static void main(String[] args) {
//用枚举的某一个实例给枚举进行赋值
Coin coin = Coin.quarter;
//赋值时,就已经将25赋给了value,再通过getValue()得到值。
System.out.println(coin.getValue());
}
}
package com.lesson5;
public enum Coin2 {
penny("hello"),nickel("world"),dime("welcome"),quarter("hi");
private String value;
public String getValue() {
return value;
}
Coin2(String value){
this.value = value;
}
public static void main(String[] args) {
Coin2 coin = Coin2.quarter;
System.out.println(coin.getValue());
}
}
定义枚举类型的本质:
定义一个枚举的时候,本质上就是在定义一个类别,只不过很多细节,都由编译器帮着完成了,所以某些程度上,enum关键字的作用就像是class或interface.
当使用”enum”关键字来定义一个枚举类别的时候,实质上定义出来的类型继承自java.lang.Enum类型,而每个枚举的成员其实就是定义的枚举类型的一个实例(interface),他们都被预设为final,所以你无法改变他们,他们也是static成员,所以可以通过类型名称直接使用他们,最重要的是,他们都是公开的(public)。
为什么会有枚举这种类型出现,在我们开发项目的时候,对于用户的权限,我们可能这样去定义,比如一个用户有增加的权限,另外的一个用户可增加,可修改。另外一个用户,可以增、删、改。对于这此权限在程序里面是怎样标识的呢,实际上是用数字来标识的。
package com.lesson5;
/**
* 枚举出现必然有它出现的理由
* @author Administrator
* 枚举类型相当于public static final Color Red;
*/
public enum Color {
Red, White, Blue;
//枚举里面不仅定义了变量,还定义了方法
//因此需要在定义变量完成之后加";",来对
//方法与变量进行分隔
public static void main(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,然而在
* 方法里面进行判断的时候,肯定就不对了
* @author Administrator
*/
// class Action{
// //判断用户到底有没有这个权限
// public Boolean canExecute(int right){
// /**
// * some judgment 做些判断
// */
// return true;
// //return false
// }
// }
/**
* 枚举的做法如下:
* 此时,传递的参数,就只能是Right类型的数据了,只能是read,write,fullControl
* 了,这样也不能传递任何其它的变量,因为这个枚举只有这三个类型的实例。这样系
* 统进行权限判断的时候,就很好判断了。
*/
enum Right{
read,write,fullControl;
}
class Action{
//判断用户到底有没有这个权限
public Boolean canExecute(Right right){
/**
* some judgment 做些判断
*/
return true;
//return false
}
}
}
枚举的比较
package com.lesson5;
/**
* 枚举的比较
*/
public class ShowEnum {
public static void main(String[] args) {
//valueof()方法可以将指定的字符串转换为枚举类型。
enumCompareTo(OpConstant.valueOf(args[0]));
}
public static void enumCompareTo(OpConstant constant){
System.out.println(constant);
//首先遍历时将OpConstant里面的对象实例取出来
//与传进命令行的参数TURN_LEFT进行相比
//发现它们俩处在同一个位置上,就返回equals 0
//接着与TURN_RIGHT相比,命令行参数是在TURN_RIGHT的
//前面,所以返回一个-1
//依此类推,前面的就返回负数。
for(OpConstant c : OpConstant.values()){
System.out.println(constant.compareTo(c));
}
}
}