java基础

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("
");
      }
   }
}

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
unoob	estRunoob.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倍。
特点:

  1. 线程安全
  2. 运行速度慢

HashSet(存储快,查询快)

  • 该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。
  • 这个类提供了基本操作(add,remove,contains和size)固定的时间性能,假定哈希函数将分散的桶中正确的元素。 迭代此集合需要与HashSet实例的大小(元素数量)和后台HashMap实例(桶数)的“容量”的总和成比例的时间。 因此,如果迭代性能很重要,不要将初始容量设置得太高(或负载因子太低)是非常重要的。
    • 初始数组长度:16. 加载因子:0.75.
    • 如果数组长度>16*0.75=12,数组就要扩容(复制)

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