六、数组
数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问它们。数组的三个基本特点:
1. 长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
2. 其元素必须是相同类型,不允许出现混合类型。
3. 数组类型可以是任何数据类型,包括基本类型和引用类型。
数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中存储的。
public class TestArray {
public static void main(String[] args) {
int[] s; //声明数组
s = new int[10]; //给数组分配空间
for (int i=0;i<10;i++) { //给数组赋值
s[i] = i*2+1;
System.out.println(s[i]);
}
System.out.println(s.length);//数组长度
}
}
public class TestMaxMin {
public static void main(String[] args) {
int max, min;
int[] s = {1,2,3,4,5};
max = s[0];
min = s[0];
System.out.print("数组s元素包括:");
for (int i=0;i<s.length;i++) {
System.out.print(s[i]+", ");
if (s[i] >= max) {
max = s[i];
}
if (s[i] <= min) {
min = s[i];
}
}
System.out.println("\n最大值为:"+max);
System.out.println("最小值 为:"+min);
}
}
1、数组初始化
静态初始化、动态初始化、默认初始化
//静态初始化:定义数组的同时,就为数组元素分配空间并赋值
int[] a = { 1, 2, 3 };// 静态初始化基本类型数组;
Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;
//动态初始化:数组定义与数组元素分配空间并赋值并分进行!
int[] a1 = new int[2];//动态初始化数组,先分配空间
a1[0]=1;//给数组元素赋值;
a1[1]=2;//给数组元素赋值;
// 默认初始化:数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,
// 其中的每个元素也被按照实例变量同样的方式被隐式初始化。
int[] a2 = new int[2]; // 默认值:0,0
boolean[] b = new boolean[2]; // 默认值:false,false
String[] s = new String[2]; // 默认值:null, null
2、for-each循环
用于读取数组或集合中所有的元素,即对数组进行遍历。类似于python的for循环。
public class Test {
public static void main(String[] args) {
String[] ss = { "aa", "bbb", "ccc", "ddd" };
for (String temp : ss) {
System.out.println(temp);
}
}
}
3、数组复制
System.arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,该方法可以将src数组里的元素值赋给dest数组的元素,其中srcpos指定从src数组的第几个元素开始赋值,length参数指定将src数组的多少个元素赋给dest数组的元素。
public class TestArray {
public static void main(String args[]) {
String[] s = {"阿里","尚学堂","京东","搜狐","网易"};
String[] sBak = new String[6];
//将s数组从第2个元素开始复制剩下的所有元素到sBak(从第3个元素开始)
System.arraycopy(s,2,sBak,3,s.length-2);
for (int i = 0; i < sBak.length; i++) {
System.out.print(sBak[i]+ "\t");
}
}
}
4、java.util.Arrays类
JDK提供的java.util.Arrays类,包含了常用的数组操作,方便我们日常开发。
Arrays类包含了:排序、查找、填充、打印内容等常见的操作。
import java.util.Arrays;
public class Test {
public static void main(String args[]) {
int[] a = {1,2,323,23,543,12,59};
System.out.println(Arrays.toString(a)); //打印数组元素的值
Arrays.sort(a); //排序
System.out.println(Arrays.toString(a));
}
}
// 数组元素是引用类型的排序(Comparable接口的应用)
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Man[] msMans = { new Man(3, "a"), new Man(60, "b"), new Man(2, "c") };
Arrays.sort(msMans);
System.out.println(Arrays.toString(msMans));
}
}
class Man implements Comparable {
int age;
int id;
String name;
public Man(int age, String name) {
super();
this.age = age;
this.name = name;
}
public String toString() {
return this.name;
}
public int compareTo(Object o) {
Man man = (Man) o;
if (this.age < man.age) {
return -1;
}
if (this.age > man.age) {
return 1;
}
return 0;
}
}
// 二分法查找
import java.util.Arrays;
public class TestArray {
public static void main(String[] args) {
int[] a = {1,2,323,23,543,12,59};
System.out.println(Arrays.toString(a));
Arrays.sort(a); //使用二分法查找,必须先对数组进行排序;
System.out.println(Arrays.toString(a));
//返回排序后新的索引位置,若未找到返回负数。
System.out.println("该元素的索引:"+Arrays.binarySearch(a, 12));
}
}
// 数组填充
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] a= {1,2,323,23,543,12,59};
System.out.println(Arrays.toString(a));
Arrays.fill(a, 2, 4, 100); //将2到4索引的元素替换为100;
System.out.println(Arrays.toString(a));
}
}
5、多维数组
多维数组可以看成是以数组为元素的数组。开发中,一般最多用到二维数组。不过一般使用容器,二维数组用得很少。
// 二维数组的声明
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
// Java中多维数组的声明和初始化应按从低维到高维的顺序进行
int[][] a = new int[3][];
a[0] = new int[2];
a[1] = new int[4];
a[2] = new int[3];
// int a1[][]=new int[][4];//非法
System.out.println(Arrays.toString(a));
}
}
public class TestShuzu {
public static void main(String[] args) {
int sum = 0;
int[][] num = {{1,2,3,4},{5,6,7,8}};
for (int[] i:num) {
System.out.println(i);
for (int j:i) {
System.out.println(j);
sum = sum+j;
}
}
System.out.println("总和为:"+sum);
}
}
// 二维数组的静态初始化
public class Test {
public static void main(String[] args) {
int[][] a = { { 1, 2, 3 }, { 3, 4 }, { 3, 5, 6, 7 } };
System.out.println(a[2][3]); //结果为7
}
}
// 二维数组的动态初始化,获取数组长度
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[][] a = new int[3][];
// a[0] = {1,2,5}; //错误, 没有声明类型就初始化
a[0] = new int[] { 1, 2 };
a[1] = new int[] { 2, 2 };
a[2] = new int[] { 2, 2, 3, 4 };
System.out.println(a[2][3]);
System.out.println(Arrays.toString(a[0]));
System.out.println(Arrays.toString(a[1]));
System.out.println(Arrays.toString(a[2]));
//获取的二维数组第一维数组的长度。
System.out.println(a.length);
//获取第二维第一个数组长度。
System.out.println(a[0].length);
}
}
6、数组存储表格数据
JAVA编译器会自动把基本数据类型“自动装箱”成包装类对象。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Object[] a1 = {1001,"高淇",18,"讲师","2006-2-14"};
Object[] a2 = {1002,"高小七",19,"助教","2007-10-10"};
Object[] a3 = {1003,"高小琴",20,"班主任","2008-5-5"};
Object[][] emps = new Object[3][];
emps[0] = a1;
emps[1] = a2;
emps[2] = a3;
System.out.println(Arrays.toString(emps[0]));
System.out.println(Arrays.toString(emps[1]));
System.out.println(Arrays.toString(emps[2]));
}
}
7、冒泡排序
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] values = {3, 1, 6, 2, 9, 0, 7, 4, 5, 8};
bubbleSort(values);
System.out.println(Arrays.toString(values));
}
public static void bubbleSort(int[] values) {
int temp;
for (int i= 0;i<values.length-1;i++) {
for (int j= 0; j<values.length-1-i;j++) {
if (values[j] > values[j+1]) {
temp = values[j+1];
values[j+1] = values[j];
values[j] = temp;
}
}
}
}
}
优化:判断每一趟是否发生了数组元素的交换,如果没有发生,则说明此时数组已经有序,无需再进行后续趟数的比较了。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] values = {3, 1, 6, 2, 9, 0, 7, 4, 5, 8};
bubbleSort(values);
System.out.println(Arrays.toString(values));
}
public static void bubbleSort(int[] values) {
int temp;
boolean flag = true;
for (int i= 0;i<values.length-1;i++) {
for (int j= 0; j<values.length-1-i;j++) {
if (values[j] > values[j+1]) {
temp = values[j+1];
values[j+1] = values[j];
values[j] = temp;
flag = false;
}
}
if (flag) {
break;
}
}
}
}
8、二分法查找
二分法检索(binary search)又称折半检索,二分法检索的基本思想是设数组中的元素从小到大有序地存放在数组(array)中,首先将给定值key与数组中间位置上元素的关键码(key)比较,如果相等,则检索成功;
否则,若key小,则在数组前半部分中继续进行二分法检索;
若key大,则在数组后半部分中继续进行二分法检索。
这样,经过一次比较就缩小一半的检索区间,如此进行下去,直到检索成功或检索失败。
二分法检索是一种效率较高的检索方法。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] arr = { 30,10,50,21,80,9,7,20,100,40,8};
int searchWord = 20; // 所要查找的数
Arrays.sort(arr); //二分法查找之前,一定要对数组元素排序
System.out.println(Arrays.toString(arr));
System.out.println(searchWord+"元素的索引:"+find(arr,searchWord));
}
public static int find(int[] array, int value) {
int low = 0;
int high = array.length -1;
while (low <= high) {
int middle = (int)(low+high)/2;
if (value == array[middle]) {
return middle;
}
if (value < array[middle]) {
high = middle-1;
}
if (value > array[middle]) {
low = middle+1;
}
}
return -1;//未找到则返回-1
}
}
七、常用类
1、包装类
Java在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。
自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转换。
自动装箱:基本类型的数据处于需要对象的环境中时,会自动转为“对象”。
自动拆箱:每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用intValue()、doubleValue()等转型方法。
自动装箱过程是通过调用包装类的valueOf()方法实现的,而自动拆箱过程是通过调用包装类的 xxxValue()方法实现的(xxx代表对应的基本数据类型,如intValue()、doubleValue()等)。
2、String类
StringBuilder和StringBuffer称之为“可变字符序列”。那两者有什么区别呢?
1. StringBuffer JDK1.0版本提供的类,线程安全,做线程同步检查, 效率较低。
2. StringBuilder JDK1.5版本提供的类,线程不安全,不做线程同步检查,因此效率较高。 建议采用该类。
StringBuilder和StringBuffer类是对原字符串本身操作的,可以对字符串进行修改而不产生副本拷贝或者产生少量的副本。
public class Test {
public static void main(String[] args) {
/**StringBuilder*/
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 7; i++) {
sb.append((char) ('a' + i));//追加单个字符
}
System.out.println(sb.toString());//转换成String输出
sb.append(", I can sing my abc!");//追加字符串
System.out.println(sb.toString());
/**StringBuffer*/
StringBuffer sb2 = new StringBuffer("中华人民共和国");
sb2.insert(0, "爱").insert(0, "我");//插入字符串
System.out.println(sb2);
sb2.delete(0, 2);//删除子字符串
System.out.println(sb2);
sb2.deleteCharAt(0).deleteCharAt(0);//删除某个字符
System.out.println(sb2);
System.out.println(sb2.charAt(0));//获取某个字符
System.out.println(sb2.reverse());//字符串逆序
}
}
public class Test {
public static void main(String[] args) {
/**使用String进行字符串的拼接*/
String str8 = "";
//本质上使用StringBuilder拼接, 但是每次循环都会生成一个StringBuilder对象
long num1 = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间
long time1 = System.currentTimeMillis();//获取系统的当前时间
for (int i = 0; i < 5000; i++) {
str8 = str8 + i;//相当于产生了10000个对象
}
long num2 = Runtime.getRuntime().freeMemory();
long time2 = System.currentTimeMillis();
System.out.println("String占用内存 : " + (num1 - num2));
System.out.println("String占用时间 : " + (time2 - time1));
/**使用StringBuilder进行字符串的拼接*/
StringBuilder sb1 = new StringBuilder("");
long num3 = Runtime.getRuntime().freeMemory();
long time3 = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
sb1.append(i);
}
long num4 = Runtime.getRuntime().freeMemory();
long time4 = System.currentTimeMillis();
System.out.println("StringBuilder占用内存 : " + (num3 - num4));
System.out.println("StringBuilder占用时间 : " + (time4 - time3));
}
}
3、时间处理相关类
3.1 Date类
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
Date date1 = new Date();
System.out.println(date1.toString());
long i = date1.getTime();//返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
Date date2 = new Date(i - 1000);
Date date3 = new Date(i + 1000);
System.out.println(date1.after(date2));
System.out.println(date1.before(date2));
System.out.println(date1.equals(date2));
System.out.println(date1.after(date3));
// System.out.println(date1.before(date3));
// System.out.println(date1.equals(date3));
System.out.println(new Date(1000L * 60 * 60 * 24 * 1L).toString());
}
}
3.2 DateFormat类
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDateFormat {
public static void main(String[] args) throws ParseException {
// new出SimpleDateFormat对象
SimpleDateFormat s1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
SimpleDateFormat s2 = new SimpleDateFormat("yyyy-MM-dd");
// 将时间对象转换成字符串
String daytime = s1.format(new Date());
System.out.println(daytime);
System.out.println(s2.format(new Date()));
System.out.println(new SimpleDateFormat("hh:mm:ss").format(new Date()));
// 将符合指定格式的字符串转成成时间对象.字符串格式需要和指定格式一致。
String time = "2007-10-7";
Date date = s2.parse(time);
System.out.println("date1: " + date);
time = "2007-10-7 20:15:30";
date = s1.parse(time);
System.out.println("date2: " + date);
}
}
import java.util.Date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;
/*接收从键盘输入的字符串格式的年龄,分数和入学时间,转换为整数、浮点数、日期类型,并在控制台输出。
提示:使用包装类Integer、Double和日期转换类DateFormat实现
*/
public class Task2 {
public static void main(String[] args) throws ParseException {
System.out.println("请依次输入年龄、分数、入学时间");
Scanner scannerage = new Scanner(System.in);
String age_str = scannerage.nextLine();
Scanner scannerscore = new Scanner(System.in);
String score_str = scannerscore.nextLine();
Scanner scannerdate = new Scanner(System.in);
String date_str = scannerscore.nextLine();
//将字符串类型数据转换为Integer、Double、DateFormat
Integer age = Integer.parseInt(age_str);
Double score = Double.parseDouble(score_str);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date date = df.parse(date_str);
// Calendar schooltime = new GregorianCalendar();
// schooltime.setTime(date);
System.out.println("您的年龄为:"+age+"\n"+"您的分数为:"+score+"\n"+
"您的入学时间为:"+date);
}
}
3.3 Calendar类
import java.util.*;
public class TestCalendar {
public static void main(String[] args) {
// 得到相关日期元素
GregorianCalendar calendar = new GregorianCalendar(1999, 10, 9, 22, 10, 50);
int year = calendar.get(Calendar.YEAR); // 打印:1999
int month = calendar.get(Calendar.MONTH); // 打印:10
int day = calendar.get(Calendar.DAY_OF_MONTH); // 打印:9
int day2 = calendar.get(Calendar.DATE); // 打印:9
// 日:Calendar.DATE和Calendar.DAY_OF_MONTH同义
int date = calendar.get(Calendar.DAY_OF_WEEK); // 打印:3
// 星期几 这里是:1-7.周日是1,周一是2,。。。周六是7
System.out.println(year);
System.out.println(month);
System.out.println(day);
System.out.println(day2);
System.out.println(date);
// 设置日期
GregorianCalendar calendar2 = new GregorianCalendar();
calendar2.set(Calendar.YEAR, 1999);
calendar2.set(Calendar.MONTH, Calendar.FEBRUARY); // 月份数:0-11
calendar2.set(Calendar.DATE, 3);
calendar2.set(Calendar.HOUR_OF_DAY, 10);
calendar2.set(Calendar.MINUTE, 20);
calendar2.set(Calendar.SECOND, 23);
printCalendar(calendar2);
// 日期计算
GregorianCalendar calendar3 = new GregorianCalendar(1999, 10, 9, 22, 10, 50);
calendar3.add(Calendar.MONTH, -7); // 月份减7
calendar3.add(Calendar.DATE, 7); // 增加7天
printCalendar(calendar3);
// 日历对象和时间对象转化
Date d = calendar3.getTime();
GregorianCalendar calendar4 = new GregorianCalendar();
calendar4.setTime(new Date());
long g = System.currentTimeMillis();
}
static void printCalendar(Calendar calendar) {
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
int date = calendar.get(Calendar.DAY_OF_WEEK) - 1; // 星期几
String week = "" + ((date == 0) ? "日" : date);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
System.out.printf("%d年%d月%d日,星期%s %d:%d:%d\n", year, month, day,
week, hour, minute, second);
}
}
4、Math类
java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型。如果需要更加强大的数学运算能力,计算高等数学中的相关内容,可以使用apache commons。
public class TestMath {
public static void main(String[] args) {
//取整相关操作
System.out.println(Math.ceil(3.2));
System.out.println(Math.floor(3.2));
System.out.println(Math.round(3.2));
System.out.println(Math.round(3.8));
//绝对值、开方、a的b次幂等操作
System.out.println(Math.abs(-45));
System.out.println(Math.sqrt(64));
System.out.println(Math.pow(5, 2));
System.out.println(Math.pow(2, 5));
//Math类中常用的常量
System.out.println(Math.PI);
System.out.println(Math.E);
//随机数
System.out.println(Math.random());// [0,1)
}
}
Math类中虽然为我们提供了产生随机数的方法Math.random(),但是通常我们需要的随机数范围并不是[0, 1)之间的double类型的数据,这就需要对其进行一些复杂的运算。如果使用Math.random()计算过于复杂的话,我们可以使用例外一种方式得到随机数,即Random类,这个类是专门用来生成随机数的,并且Math.random()底层调用的就是Random的nextDouble()方法。
import java.util.Random;
public class TestRandom {
public static void main(String[] args) {
Random rand = new Random();
//随机生成[0,1)之间的double类型的数据
System.out.println(rand.nextDouble());
//随机生成int类型允许范围之内的整型数据
System.out.println(rand.nextInt());
//随机生成[0,1)之间的float类型的数据
System.out.println(rand.nextFloat());
//随机生成false或者true
System.out.println(rand.nextBoolean());
//随机生成[0,10)之间的int类型的数据
System.out.print(rand.nextInt(10));
//随机生成[20,30)之间的int类型的数据
System.out.print(20 + rand.nextInt(10));
//随机生成[20,30)之间的int类型的数据(此种方法计算较为复杂)
System.out.print(20 + (int) (rand.nextDouble() * 10));
}
}
5、File类
java.io.File类:代表文件和目录。 在开发中,读取文件、生成文件、删除文件、修改文件的属性时经常会用到本类。
在eclipse项目开发中,user.dir就是本项目的目录。
// 文件创建
import java.io.File;
public class TestFile1 {
public static void main(String[] args) throws Exception {
System.out.println(System.getProperty("user.dir"));
File f = new File("a.txt"); //相对路径:默认放到user.dir目录下面
f.createNewFile();//创建文件
File f2 = new File("d:/b.txt");//绝对路径
f2.createNewFile();
}
}
import java.io.File;
import java.util.Date;
public class TestFile1 {
public static void main(String[] args) throws Exception {
File f = new File("d:/b.txt");
System.out.println("File是否存在:"+f.exists());
System.out.println("File是否是目录:"+f.isDirectory());
System.out.println("File是否是文件:"+f.isFile());
System.out.println("File最后修改时间:"+new Date(f.lastModified()));
System.out.println("File的大小:"+f.length());
System.out.println("File的文件名:"+f.getName());
System.out.println("File的目录路径:"+f.getPath());
}
}
import java.io.File;
public class TestFile1 {
public static void main(String[] args) throws Exception {
File f = new File("d:/c.txt");
f.createNewFile(); // 会在d盘下面生成c.txt文件
f.delete(); // 将该文件或目录从硬盘上删除
File f2 = new File("d:/电影/华语/大陆");
boolean flag = f2.mkdir(); //目录结构中有一个不存在,则不会创建整个目录树
System.out.println(flag);//创建失败,false
boolean flag2 = f2.mkdirs();//目录结构中有一个不存在也没关系;创建整个目录树
System.out.println(flag2);//创建成功.true
}
}
import java.io.File;
import java.io.IOException;
public class TestFile1 {
public static void main(String[] args) {
//指定一个文件
File file = new File("d:/sxt/b.txt");
//判断该文件是否存在
boolean flag= file.exists();
//如果存在就删除,如果不存在就创建
if(flag){
//删除
boolean flagd = file.delete();
if(flagd){
System.out.println("删除成功");
}else{
System.out.println("删除失败");
}
}else{
//创建
boolean flagn = true;
try {
//如果目录不存在,先创建目录
File dir = file.getParentFile();//获得父目录
dir.mkdirs();
//创建文件
flagn = file.createNewFile();
System.out.println(flagn);
System.out.println("创建成功");
} catch (IOException e) {
System.out.println("创建失败");
e.printStackTrace();
}
}
//文件重命名
file.renameTo(new File("d:/sxt/readme.txt"));
}
}
递归遍历目录结构和树状展现
import java.io.File;
public class TestFile1 {
public static void main(String[] args) {
File f = new File("d:/电影");
printFile(f, 0);
}
/**
* 打印文件信息
* @param file 文件名称
* @param level 层次数(实际就是:第几次递归调用)
*/
static void printFile(File file, int level) {
//输出层次数
for (int i = 0; i < level; i++) {
System.out.print("-");
}
//输出文件名
System.out.println(file.getName());
//如果file是目录,则获取子文件列表,并对每个子文件进行相同的操作
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File temp : files) {
//递归调用该方法:注意等+1
printFile(temp, level + 1);
}
}
}
}
6、枚举
import java.util.Random;
public class TestFile1{
public static void main(String[] args) {
// 枚举遍历
for (Week k : Week.values()) {
System.out.println(k);
}
// switch语句中使用枚举
int a = new Random().nextInt(4); // 生成0,1,2,3的随机数
switch (Season.values()[a]) {
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINDTER:
System.out.println("冬天");
break;
}
}
}
/**季节*/
enum Season {
SPRING, SUMMER, AUTUMN, WINDTER
}
/**星期*/
enum Week {
星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期日
}
import java.text.ParseException;
import java.util.Scanner;
/*
根据交通信号灯颜色决定汽车停车、行驶和慢行
提示:使用枚举实现
*/
public class Task3 {
public static void main(String[] args) throws ParseException {
for (Color c:Color.values()) {
System.out.println(c);
}
//获取键盘输入
Scanner scanner = new Scanner(System.in);
System.out.print("请输入1-3数值:");
int color = scanner.nextInt();
switch (Color.values()[color-1]) {
case red:
System.out.println("停车");
break;
case green:
System.out.println("行驶");
break;
case yellow:
System.out.println("慢行");
break;
}
}
}
enum Color {
red,green,yellow//三种颜色相当于三个变量
}
八、容器
通过“容器”(也叫集合Collection)来容纳和管理数据。数组就是一种容器,可以在其中放置对象或基本类型数据。
数组的优势:是一种简单的线性序列,可以快速地访问数组元素,效率高。如果从效率和类型检查的角度讲,数组是最好的。
数组的劣势:不灵活。容量需要事先定义好,不能随着需求的变化而扩容。比如:我们在一个用户管理系统中,要把今天注册的所有用户取出来,那么这样的用户有多少个?我们在写程序时是无法确定的。因此,在这里就不能使用数组。
泛型的本质就是“数据类型的参数化”。 我们可以把“泛型”理解为数据类型的一个占位符(形式参数),即告诉编译器,在调用泛型时必须传入实际类型。加上泛型的好处就是不用强制转换。
下面是定义泛型方法的规则:
- 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的<E>)。
- 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
- 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
- 泛型方法方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int,double,char 的等)。
// 泛型方法,打印不同类型的字符串元素
public class GenericMethodTest
{
// 泛型方法 printArray
public static < E > void printArray( E[] inputArray )
{
// 输出数组元素
for ( E element : inputArray ){
System.out.printf( "%s ", element );
}
System.out.println();
}
public static void main( String args[] )
{
// 创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
System.out.println( "Array integerArray contains:" );
printArray( intArray ); // 传递一个整型数组
System.out.println( "\nArray doubleArray contains:" );
printArray( doubleArray ); // 传递一个双精度型数组
System.out.println( "\nArray characterArray contains:" );
printArray( charArray ); // 传递一个字符型型数组
}
}
Collection List Set
// list的常用方法
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
// 测试add/remove/size/isEmpty/contains/clear/toArrays
public class TestList01 {
public static void main(String[] args) {
test01();
}
public static void test01() {
List<String> list = new ArrayList<String>();
System.out.println(list.isEmpty());
list.add("张三");
System.out.println(list.isEmpty());
list.add("李四");
list.add("王五");
System.out.println(list);
System.out.println(list.size());
System.out.println("是否包含元素:"+list.contains("张三"));
list.remove("王五");
System.out.println(list);
Object[] objs = list.toArray();//list转换成Object数组
System.out.println(Arrays.toString(objs));
}
}
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class TestList01 {
public static void main(String[] args) {
test02();
}
public static void test02() {
//两个list之间的元素处理
List<String> list1 = new ArrayList<String>();
list1.add("张三");
list1.add("李四");
List<String> list2 = new ArrayList<String>();
list2.add("张三");
list2.add("李四");
list2.add("王五");
System.out.println(list2.containsAll(list1));//list2是否包含list1中的所有元素
list2.addAll(list1);//将list1的元素添加到list2中
System.out.println(list1);
System.out.println(list2);
list2.removeAll(list1);//从list2中删除同时在list1和list2中的元素
System.out.println(list2);
list2.retainAll(list1);//取list2和list1的交集,list2变成交集
System.out.println(list2);
}
}
public class TestList {
public static void main(String[] args) {
test03();
}
// list中操作索引的常用方法
public static void test03() {
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
System.out.println(list); // [A, B, C, D]
list.add(2, "高");
System.out.println(list); // [A, B, 高, C, D]
list.remove(2);
System.out.println(list); // [A, B, C, D]
list.set(2, "c");
System.out.println(list); // [A, B, c, D]
System.out.println(list.get(1)); // 返回:B
list.add("B");
System.out.println(list); // [A, B, c, D, B]
System.out.println(list.indexOf("B")); // 1 从头到尾找到第一个"B"
System.out.println(list.lastIndexOf("B")); // 4 从尾到头找到第一个"B"
}
}
如何选用ArrayList、LinkedList、Vector?
1. 需要线程安全时,用Vector。
2. 不存在线程安全问题时,并且查找较多用ArrayList(一般使用它)。
3. 不存在线程安全问题时,增加或删除元素较多用LinkedList。