java基础
- java修饰符#
- Java包#
- Import语句#
- 内置数据类型#
- Java 常量#
- Java 循环结构#
- 日期时间#
- 使用printf格式化日期#
- 继承#
- instanceof 关键字(比较引用类型)#
- 包#
- StringBuffer 和 StringBuilder 类#
- 正则表达式#
- Arrays数组工具类#
- 数据集合框架#
- ArrarList数组#
- LinkedList链表(增删快,查询慢)#
- Vector (淘汰)#
- HashSet(存储快,查询快)#
- LinkedHashSet#
- HashMap#
- 斗地主案例:#
- LinkedHashSet#
- Hashtable(淘汰)#
- Properties#
- 可变参数#
- 异常处理#
java修饰符#
访问控制修饰符 : default, public , protected, private
修饰符 | 说明 |
---|---|
default (即缺省,什么也不写) | 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。 |
private | 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类) |
public | 对所有类可见。使用对象:类、接口、变量、方法 |
protected | 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。 |
非访问控制修饰符 : final, abstract, strictfp
修饰符 | 说明 |
---|---|
final | 用来修饰类方法和类变量 |
abstract | 用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。abstract 修饰符,用来创建抽象类和抽象方法。 |
synchronized | synchronized 和 volatile 修饰符,主要用于线程的编程。 |
synchronized 修饰符#
synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。
实例
public synchronized void showDetails(){
.......
}
transient 修饰符#
序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
实例
public transient int limit = 55; // 不会持久化
public int b; // 持久化
volatile 修饰符#
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。
实例
public class MyRunnable implements Runnable
{
private volatile boolean active;
public void run()
{
active = true;
while (active) // 第一行
{
// 代码
}
}
public void stop()
{
active = false; // 第二行
}
}
通常情况下,在一个线程调用 run() 方法(在 Runnable 开启的线程),在另一个线程调用 stop() 方法。 如果 第一行 中缓冲区的 active 值被使用,那么在 第二行 的 active 值为 false 时循环不会停止。
但是以上代码中我们使用了 volatile 修饰 active,所以该循环会停止。
Java包#
包主要用来对类和接口进行分类。当开发Java程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。
Import语句#
在Java中,如果给出一个完整的限定名,包括包名、类名,那么Java编译器就可以很容易地定位到源代码或者类。Import语句就是用来提供一个合理的路径,使得编译器可以找到某个类。
例如,下面的命令行将会命令编译器载入java_installation/java/io路径下的所有类
import java.io.*;
内置数据类型#
byte
:数据类型是8位、有符号的,以二进制补码表示的整数;
最小值是 -128(-2^7);
最大值是 127(2^7-1);
short
:short 数据类型是 16 位、有符号的以二进制补码表示的整数
最小值是 -32768(-2^15);
最大值是 32767(2^15 - 1);
long
数据类型是 64 位、有符号的以二进制补码表示的整数;
最小值是 -9,223,372,036,854,775,808(-2^63);
最大值是 9,223,372,036,854,775,807(2^63 -1);
这种类型主要使用在需要比较大整数的系统上;
默认值是 0L
;
float
数据类型是单精度、32位、符合IEEE 754标准的浮点数;
float 在储存大型浮点数组的时候可节省内存空间;
默认值是 0.0f
;
浮点数不能用来表示精确的值,如货币;
例子:float f1 = 234.5f。
double
数据类型是双精度、64 位、符合IEEE 754标准的浮点数;
浮点数的默认类型为double类型;
double类型同样不能表示精确的值,如货币;
默认值是 0.0d;
例子:double d1 = 123.4。
Java 常量#
在 Java 中使用 final 关键字来修饰常量,
final double PI = 3.1415927;
Java 循环结构#
while 循环#
while是最基本的循环,它的结构为:
while( 布尔表达式 ) {
//循环内容
}
do…while 循环#
对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。
do {
//代码语句
}while(布尔表达式);
for循环#
虽然所有循环结构都可以用 while 或者 do...while表示,但 Java 提供了另一种语句 —— for 循环,使一些循环结构变得更加简单。
for循环执行的次数是在执行前就确定的。语法格式如下:
for(初始化; 布尔表达式; 更新) {
//代码语句
}
实例
public class Test {
public static void main(String args[]) {
for(int x = 10; x < 20; x = x+1) {
System.out.print("value of x : " + x );
System.out.print("\n");
}
}
}
Java 增强 for 循环#
Java5 引入了一种主要用于数组的增强型 for 循环。
Java 增强 for 循环语法格式如下:
for(声明语句 : 表达式)
{
//代码句子
}
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法
break 关键字#
break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块。
break 跳出最里层的循环,并且继续执行该循环下面的语句。
continue 关键字#
continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。
在 for 循环中,continue 语句使程序立即跳转到更新语句。
在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。
日期时间#
// 初始化 Date 对象
Date date = new Date();
日期比较#
Java使用以下三种方法来比较两个日期:
使用 getTime()
方法获取两个日期(自1970年1月1日经历的毫秒数值),然后比较这两个值。
使用方法 before()
,after()
和 equals()
。例如,一个月的12号比18号早,则 new Date(99, 2, 12).before(new Date (99, 2, 18)) 返回true。
使用 compareTo()
方法,它是由 Comparable 接口定义的,Date 类实现了这个接口。
使用 SimpleDateFormat 格式化日期#
SimpleDateFormat
是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行。例如:
import java.util.*;
import java.text.*;
public class DateDemo {
public static void main(String args[]) {
Date dNow = new Date( );
SimpleDateFormat ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
System.out.println("Current Date: " + ft.format(dNow));
}
}
使用printf格式化日期#
转 换 符 | 说 明 | 示 例 |
---|---|---|
c | 包括全部日期和时间信息 | 星期六 十月 27 14:21:20 CST 2007 |
F | "年-月-日"格式 | 2007-10-27 |
D | "月/日/年"格式 | 10/27/07 |
r | "HH:MM:SS PM"格式(12时制) | 02:25:51 下午 |
T | "HH:MM:SS"格式(24时制) | 14:28:16 |
R | "HH:MM"格式(24时制) | 14:28 |
字符串转时间 parse#
SimpleDateFormat 类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat 对象的格式化存储来解析字符串。例如:
import java.util.*;
import java.text.*;
public static void main(String args[]) {
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd");
String input = args.length == 0 ? "1818-11-11" : args[0];
System.out.print(input + " Parses as ");
Date t;
try {
t = ft.parse(input);
System.out.println(t);
} catch (ParseException e) {
System.out.println("Unparseable using " + ft);
}
}
//结果:2015-11-11 Parses as Wed Nov 11 00:00:00 UTC 2015
Calendar类#
我们现在已经能够格式化并创建一个日期对象了,但是我们如何才能设置和获取日期数据的特定部分呢,比如说小时,日,或者分钟? 我们又如何在日期的这些部分加上或者减去值呢? 答案是使用Calendar 类。
Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类要复杂一些。
Calendar类对象字段类型#
常量 | 描述 | 取值 |
---|---|---|
Calendar.YEAR | 年份 | |
Calendar.MONTH | 月份 | 0-11 |
Calendar.DATE | 日期 | |
Calendar.HOUR | 12小时制的小时 | |
Calendar.HOUR_OF_DAY | 24小时制的小时 | |
Calendar.MINUTE | 分钟 | |
Calendar.SECOND | 秒 | |
Calendar.DAY_OF_WEEK | 星期几 | 0-6 |
Calendar.DAY_OF_MONTH | 这个月第几天 | |
Calendar.DAY_OF_YEAR | 今年的第几天 | |
Calendar.WEEK_OF_YEAR | 今年第几个星期 | |
Calendar.WEEK_OF_MONTH | 这个月第几个星期 |
Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
创建一个代表系统当前日期的Calendar对象
Calendar c = Calendar.getInstance();//默认是当前日期
创建一个指定日期的Calendar对象
使用Calendar类代表特定的时间,需要首先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。
Calendar类对象信息的设置#
1.get获取
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR); //年份
int month = c.get(Calendar.MONTH)+1; //月数
int day = c.get(Calendar.DATE); //天数
System.out.printf("%d-%d-%d",year,month,day);
}
//2018-8-3
2.Set设置
返回值 | Set 方法 | |
---|---|---|
void | set(int field, int value) 将给定的日历字段设置为给定的值。 |
c1.set(Calendar.MONTH , 9); |
void | set(int year, int month, int date) 设置日历字段中的值 YEAR , MONTH和 DAY_OF_MONTH 。 |
|
void | set(int year, int month, int date, int hourOfDay, int minute) 设置日历字段中的值 YEAR , MONTH , DAY_OF_MONTH , HOUR_OF_DAY和 MINUTE 。 |
|
void | set(int year, int month, int date, int hourOfDay, int minute, int second) 设置字段中的值 YEAR , MONTH , DAY_OF_MONTH , HOUR_OF_DAY , MINUTE和 SECOND 。 |
//创建一个代表2009年6月12日的Calendar对象
Calendar c1 = Calendar.getInstance();
c1.set(2009, 6 - 1, 12);
int year1 = c1.get(Calendar.YEAR); //年份
int month1 = c1.get(Calendar.MONTH)+1; //月数
int day1 = c1.get(Calendar.DATE); //天数
System.out.printf("%d-%d-%d",year1,month1,day1);
//2009-6-12
3.add偏移量
Calendar c2 = Calendar.getInstance(); //2018-8-3
//c2.add(Calendar.DATE, -9); //2018-7-25
//c2.add(Calendar.DATE, 9); //2018-8-12
//c2.add(Calendar.DAY_OF_MONTH, 9); //2018-8-12
c2.add(Calendar.DAY_OF_YEAR, -9); //2018-8-12
GregorianCalendar类#
Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。
Calendar 的getInstance()方法返回一个默认用当前的语言环境和时区初始化的GregorianCalendar对象。GregorianCalendar定义了两个字段:AD和BC。这是代表公历定义的两个时代。
import java.util.*;
public class GregorianCalendarDemo {
public static void main(String args[]) {
String months[] = {
"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"};
int year;
// 初始化 Gregorian 日历
// 使用当前时间和日期
// 默认为本地时间和时区
GregorianCalendar gcalendar = new GregorianCalendar();
// 显示当前时间和日期的信息
System.out.print("Date: ");
System.out.print(months[gcalendar.get(Calendar.MONTH)]);
System.out.print(" " + gcalendar.get(Calendar.DATE) + " ");
System.out.println(year = gcalendar.get(Calendar.YEAR));
System.out.print("Time: ");
System.out.print(gcalendar.get(Calendar.HOUR) + ":");
System.out.print(gcalendar.get(Calendar.MINUTE) + ":");
System.out.println(gcalendar.get(Calendar.SECOND));
// 测试当前年份是否为闰年
if(gcalendar.isLeapYear(year)) {
System.out.println("当前年份是闰年");
}
else {
System.out.println("当前年份不是闰年");
}
}
}
/*
结果:
Date: Nov 9 2016
Time: 8:44:54
当前年份是闰年
*/
继承#
类继承:类 extends 类
接口继承:类 implements 接口
public interface ICar {
/**
* 接口中的成员特点
* 1.成员变量的特点,没有变量,都是常量
* final 最终固定住变量的值
* 相当于 const
*/
public static final int x = 3;
}
super 与 this 关键字#
super关键字(相当于C#的base):我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。
instanceof 关键字(比较引用类型)#
数据类型判断。
instanceof 的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
/*
author by runoob.com
Main.java
*/
import java.util.ArrayList;
import java.util.Vector;
public class Main {
public static void main(String[] args) {
Object testObject = new ArrayList();
displayObjectClass(testObject);
}
public static void displayObjectClass(Object o) {
if (o instanceof Vector)
System.out.println("对象是 java.util.Vector 类的实例");
else if (o instanceof ArrayList)
System.out.println("对象是 java.util.ArrayList 类的实例");
else
System.out.println("对象是 " + o.getClass() + " 类的实例");
}
}
//对象是 java.util.ArrayList 类的实例
包#
为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
通常,一个公司使用它互联网域名的颠倒形式来作为它的包名.例如:互联网域名是 runoob.com,所有的包名都以 com.runoob 开头。包名中的每一个部分对应一个子目录。
例如:有一个 com.runoob.test 的包,这个包包含一个叫做 Runoob.java 的源文件,那么相应的,应该有如下面的一连串子目录:
....\com\runoob\test\Runoob.java
StringBuffer 和 StringBuilder 类#
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder
相较于 StringBuffer
有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
StringBuffer 方法
描述 | |
---|---|
1 | public StringBuffer reverse() 将此字符序列用其反转形式取代。 |
2 | public StringBuffer append(String s) 将指定的字符串追加到此字符序列。 |
3 | public delete(int start, int end) 移除此序列的子字符串中的字符。 |
4 | public insert(int offset, int i) 将 int 参数的字符串表示形式插入此序列中。 |
5 | replace(int start, int end, String str) 使用给定 String 中的字符替换此序列的子字符串中的字符 |
正则表达式#
java.util.regex
包主要包括以下三个类:
Pattern
类:
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
Matcher
类:
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
PatternSyntaxException
:
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
//匹配 返回true或false
public boolean matches(String regex) {
return Pattern.matches(regex, this);
}
//regex 正则
//replacement 替换内容
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
//使用正则将字符串切割
public String split(String regex)
Arrays数组工具类#
binarySearch
使用二进制搜索算法搜索指定值的指定字节数组。 在进行此调用之前,数组必须按照sort(byte[])方法进行排序。 如果没有排序,结果是未定义的。 如果数组包含具有指定值的多个元素,则不能保证将找到哪个元素。
int[] array = {1,4,7,9,11,13,15,18};
/**
* 数组的二分搜索法
* 返回元素在数组中的索引
* 元素不存在。返回 (-(插入点) - 1)
*/
// Integer index = Arrays.binarySearch(array,11); //4
Integer index = Arrays.binarySearch(array,10); // (-4-1)=-5
System.out.println(index);
数组复制
System.arraycopy(src, srcPos, dest, destPos, length)
方法,推荐使用
public static void main(String[] args) {
int[] arr = {90,70,80,60,64,57,85,76,74,88};
int[] result = test(arr);
System.out.println(Arrays.toString(result));
// 结果:[57, 60, 64]
}
public static int[] test(int[] array){
Arrays.sort(array);
/**
* arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
将指定源数组中的数组从指定位置复制到目标数组的指定位置。
src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目的地数据中的起始位置。
length - 要复制的数组元素的数量。
*/
int[] result = new int[3];
System.arraycopy(array,0,result,0,3);
return result;
}
数据集合框架#
ArrarList
数组#
该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。
LinkedList
链表(增删快,查询慢)#
该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:
Listlist=Collections.synchronizedList(newLinkedList(...));
LinkedList 查找效率低。
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("abc");
linkedList.add("bcd");
linkedList.add("cde");
System.out.println(linkedList); //[abc, bcd, cde]
//addFirst 在该列表开头插入指定的元素。
linkedList.addFirst("1");
linkedList.addFirst("2");
System.out.println(linkedList); //[2, 1, abc, bcd, cde]
//addLast 将指定的元素追加到此列表的末尾。
linkedList.addLast("haha1");
linkedList.addLast("haha2");
System.out.println(linkedList); //[2, 1, abc, bcd, cde, haha1, haha2]
if (!linkedList.isEmpty()) {
//getFirst() 返回此列表中的第一个元素。
String first = linkedList.getFirst();
//getLast() 返回此列表中的最后一个元素。
String last = linkedList.getLast();
System.out.println(first); //2
System.out.println(last); //haha2
}
//pop 删除并返回此列表的第一个元素 此方法相当于removeFirst() 。
linkedList.pop();
System.out.println(linkedList);
//push 在该列表的前面插入元素 此方法相当于addFirst(E) 。
linkedList.push("ccc");
System.out.println(linkedList);
}
Vector
(淘汰)#
该类和ArrayList非常相似,但是该类是同步
的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。
特点:
- 线程安全
- 运行速度慢
HashSet
(存储快,查询快)#
- 该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。
- 这个类提供了基本操作(add,remove,contains和size)固定的时间性能,假定哈希函数将分散的桶中正确的元素。 迭代此集合需要与HashSet实例的大小(元素数量)和后台HashMap实例(桶数)的“容量”的总和成比例的时间。 因此,如果迭代性能很重要,不要将初始容量设置得太高(或负载因子太低)是非常重要的。
LinkedHashSet#
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。
- 继承自HashSet。
- 线程不安全。
- 有序的。
HashMap#
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。
返回值 | 方法 | 描述 |
---|---|---|
V | put(K key, V value) | 将指定的值与此映射中的指定键相关联 返回值:一般为null,存在重复键,返回覆盖前的值 |
V | get(Object key) | 返回到指定键所映射的值。 |
V | remove(Object key) | 从该地图中删除指定键的映射(如果存在)。 |
Set<K> |
keySet() | 返回此地图中包含的键的Set视图。 |
Set<Map.Entry<K,V>> |
entrySet() | 返回此地图中包含的映射的Set视图。 |
Map的遍历方式:#
- 键查找:
1.keySet() 得到所有键。
2.遍历Set<K>
集合。
3.get() 根据键得到value。
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1,"a");
map.put(2,"b");
map.put(3,"c");
Set<Integer> set = map.keySet();
Iterator<Integer> it = set.iterator();
while (it.hasNext()){
int key = it.next();
String value = map.get(key);
System.out.print(value + " ");
}
Map.Entry<K,V>
通过键值对,找键,找值
1.调用entrySet() 将集合映射关系存储到Set集合Set<Map.Entry<K,V>>
2.迭代Set集合
3.通过getKey,getValue获取键值对
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
Set<Map.Entry<Integer, String>> setlist = map.entrySet();
for (Map.Entry<Integer, String> set : setlist ) {
System.out.println(set.getKey()+":"+set.getValue());
}
// 1:a
// 2:b
// 3:c
}
斗地主案例:#
public class PuKe {
public static void main(String[] args) {
String[] numbers = {"2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3"};
String[] colors = {"♠", "♥", "♣", "♦"};
ArrayList<Integer> plaer1 = new ArrayList();
ArrayList<Integer> plaer2 = new ArrayList();
ArrayList<Integer> plaer3 = new ArrayList();
ArrayList<Integer> bottom = new ArrayList();
//key 序号 value 牌
//完成数字与纸牌的映射关系:使用双列Map(HashMap)集合,完成一个数字与字符串纸牌的对应关系(相当于一个字典)。
HashMap<Integer, String> pooker = new HashMap<>();
ArrayList<Integer> arrayList = new ArrayList();
int index = 2;
for (String number : numbers
) {
for (String color : colors
) {
//从2开始,0:大王,1:小王
pooker.put(index, color + number);
arrayList.add(index);
index++;
}
}
pooker.put(0, "大王");
pooker.put(1, "小王");
arrayList.add(0);
arrayList.add(1);
//
System.out.println("hasMap映射的数字数组(单独):"+arrayList);
//洗牌
Collections.shuffle(arrayList);
System.out.println("洗牌后,hasMap映射的数字数组(单独):"+arrayList);
//发牌
bottom.add(arrayList.get(arrayList.size() - 1));
bottom.add(arrayList.get(arrayList.size() - 2));
bottom.add(arrayList.get(arrayList.size() - 3));
for (int i = 0; i < arrayList.size() - 3; i++) {
switch (i % 3) {
case 0:
plaer1.add(arrayList.get(i));
break;
case 1:
plaer2.add(arrayList.get(i));
break;
case 2:
plaer3.add(arrayList.get(i));
break;
}
}
System.out.println("=====分配到玩家手里的牌====");
System.out.println(plaer1);
System.out.println(plaer2);
System.out.println(plaer3);
System.out.println(bottom);
Collections.sort(plaer1);
Collections.sort(plaer2);
Collections.sort(plaer3);
System.out.println("=====玩家手里的牌,排序后====");
System.out.println(plaer1);
System.out.println(plaer2);
System.out.println(plaer3);
System.out.println(bottom);
System.out.println("====查看手里的牌在hasMap映射后的结果=====");
System.out.print("plaer1:");
look(plaer1, pooker);
System.out.print("plaer2:");
look(plaer2, pooker);
System.out.print("plaer3:");
look(plaer3, pooker);
System.out.print("bottom:");
look(bottom, pooker);
}
//看牌
public static void look(ArrayList<Integer> arrayList, HashMap<Integer, String> pooker) {
for (Integer key : arrayList
) {
String value = pooker.get(key);
System.out.print(value + " ");
}
System.out.println();
}
hasMap映射的数字数组(单独):[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 0, 1]
洗牌后,hasMap映射的数字数组(单独):[44, 19, 39, 16, 34, 32, 24, 35, 7, 18, 8, 17, 26, 23, 29, 47, 48, 4, 12, 51, 15, 6, 0, 46, 50, 30, 43, 22, 36, 42, 33, 1, 27, 53, 13, 38, 49, 41, 21, 10, 40, 14, 20, 37, 3, 25, 28, 9, 31, 45, 52, 2, 5, 11]
=====分配到玩家手里的牌====
[44, 16, 24, 18, 26, 47, 12, 6, 50, 22, 33, 53, 49, 10, 20, 25, 31]
[19, 34, 35, 8, 23, 48, 51, 0, 30, 36, 1, 13, 41, 40, 37, 28, 45]
[39, 32, 7, 17, 29, 4, 15, 46, 43, 42, 27, 38, 21, 14, 3, 9, 52]
[11, 5, 2]
=====玩家手里的牌,排序后====
[6, 10, 12, 16, 18, 20, 22, 24, 25, 26, 31, 33, 44, 47, 49, 50, 53]
[0, 1, 8, 13, 19, 23, 28, 30, 34, 35, 36, 37, 40, 41, 45, 48, 51]
[3, 4, 7, 9, 14, 15, 17, 21, 27, 29, 32, 38, 39, 42, 43, 46, 52]
[11, 5, 2]
====查看手里的牌在hasMap映射后的结果=====
plaer1:♠A ♠K ♣K ♣Q ♠J ♣J ♠10 ♣10 ♦10 ♠9 ♥8 ♦8 ♣5 ♥4 ♦4 ♠3 ♦3
plaer2:大王 小王 ♣A ♦K ♥J ♥10 ♣9 ♠8 ♠7 ♥7 ♣7 ♦7 ♣6 ♦6 ♦5 ♣4 ♥3
plaer3:♥2 ♣2 ♥A ♦A ♠Q ♥Q ♦Q ♦J ♥9 ♦9 ♣8 ♠6 ♥6 ♠5 ♥5 ♠4 ♣3
bottom:♥K ♦2 ♠2
LinkedHashSet#
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。
Hashtable(淘汰)#
Hashtable 是 Dictionary(字典) 类的子类,位于 java.util 包中。
- 线程安全。
- 不能存null。
Properties#
Properties 继承于 Hashtable,表示一个持久的属性集,属性列表中每个键及其对应值都是一个字符串。
可变参数#
数据类型...变量
1.一个方法中,可变参只能有1个
2.可变参数,必须写在参数列表的最后一位
System.out.println(Sum(1,2,3,5,6));
public static int Sum(int...a){
int result= 0;
for (int model: a
) {
result +=model;
}
return result;
}
//2.可变参数,必须写在参数列表的最后一位
public static int Del(int a,int b,int...c)
异常处理#
要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:
洒洒水
- 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。(不能发生,如果发生必须修改源代码)
- 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
throws/throw 关键字:#
如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
public static void main(String[] args) throws Exception {
// Method implementation
throw new RemoteException();
}
异常方法#
下面的列表是 Throwable 类的主要方法:
方法 | 说明 |
---|---|
public String getMessage() | 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。 |
public Throwable getCause() | 返回一个Throwable 对象代表异常原因。 |
public String toString() | 使用getMessage()的结果返回类的串级名字。 |
public void printStackTrace() | 打印toString()结果和栈层次到System.err,即错误输出流。 |
public StackTraceElement [] getStackTrace() | 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。 |
public Throwable fillInStackTrace() | 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。 |
作者:【唐】三三
出处:https://www.cnblogs.com/tangge/p/9391370.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2013-07-30 EasyUi – 2.布局Layout + 3.登录界面