java基础

java修饰符

访问控制修饰符 : default, public , protected, private

修饰符说明
default (即缺省,什么也不写)在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
private在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
public对所有类可见。使用对象:类、接口、变量、方法
protected对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。

非访问控制修饰符 : final, abstract, strictfp

修饰符说明
final用来修饰类方法和类变量
abstract用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。abstract 修饰符,用来创建抽象类和抽象方法。
synchronizedsynchronized 和 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.HOUR12小时制的小时
Calendar.HOUR_OF_DAY24小时制的小时
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 方法
voidset(int field, int value)
将给定的日历字段设置为给定的值。
c1.set(Calendar.MONTH , 9);
voidset(int year, int month, int date)
设置日历字段中的值 YEAR , MONTH和 DAY_OF_MONTH 。
voidset(int year, int month, int date, int hourOfDay, int minute)
设置日历字段中的值 YEAR , MONTH , DAY_OF_MONTH , HOUR_OF_DAY和 MINUTE 。
voidset(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 方法

描述
1public StringBuffer reverse()
将此字符序列用其反转形式取代。
2public StringBuffer append(String s)
将指定的字符串追加到此字符序列。
3public delete(int start, int end)
移除此序列的子字符串中的字符。
4public insert(int offset, int i)
将 int 参数的字符串表示形式插入此序列中。
5replace(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,数组就要扩容(复制)
      196558-20180806110051790-1702576910.png

LinkedHashSet

具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。

  • 继承自HashSet。
  • 线程不安全。
  • 有序的

HashMap

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。

返回值方法描述
Vput(K key, V value)将指定的值与此映射中的指定键相关联
返回值:一般为null,存在重复键,返回覆盖前的值
Vget(Object key)返回到指定键所映射的值。
Vremove(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 对象栈层次,添加到栈层次任何先前信息中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值