首页 > 编程语言 >Java-003

Java-003

时间:2024-07-28 18:08:47浏览次数:8  
标签:Java String System 003 println new public out

集合进阶

集合容器中只能存放对象,基本数据类型需要使用对应的包装类

Collection单列集合

collection集合体系 image-20240406200830075

collection常用方法

image-20240406200840494

package com.itheima.d1_collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.IntFunction;

/**
    目标:掌握Collection集合的常用API.
    Collection是集合的祖宗类,它的功能是全部集合都可以继承使用的,所以要学习它。
    Collection API如下:
         - public boolean add(E e):  把给定的对象添加到当前集合中 。
         - public void clear() :清空集合中所有的元素。
         - public boolean remove(E e): 把给定的对象在当前集合中删除。
         - public boolean contains(Object obj): 判断当前集合中是否包含给定的对象。
         - public boolean isEmpty(): 判断当前集合是否为空。
         - public int size(): 返回集合中元素的个数。
         - public Object[] toArray(): 把集合中的元素,存储到数组中。
 */
public class CollectionTest2API {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>(); // 多态写法
        // 1.public boolean add(E e):添加元素, 添加成功返回true。
        c.add("java1");
        c.add("java1");
        c.add("java2");
        c.add("java2");
        c.add("java3");
        System.out.println(c);

        // 2.public void clear():清空集合的元素。
        //c.clear();
        //System.out.println(c);

        // 3.public boolean isEmpty():判断集合是否为空 是空返回true,反之。
        System.out.println(c.isEmpty()); // false

        // 4.public int size():获取集合的大小。
        System.out.println(c.size());

        // 5.public boolean contains(Object obj):判断集合中是否包含某个元素。
        System.out.println(c.contains("java1")); // true
        System.out.println(c.contains("Java1")); // false

        // 6.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
        System.out.println(c.remove("java1"));
        System.out.println(c);

        // 7.public Object[] toArray():把集合转换成数组
        Object[] arr = c.toArray();
        System.out.println(Arrays.toString(arr));

        String[] arr2 = c.toArray(new String[c.size()]);
        System.out.println(Arrays.toString(arr2));

        System.out.println("--------------------------------------------");
        // 把一个集合的全部数据倒入到另一个集合中去。
        Collection<String> c1 = new ArrayList<>();
        c1.add("java1");
        c1.add("java2");
        Collection<String> c2 = new ArrayList<>();
        c2.add("java3");
        c2.add("java4");
        c1.addAll(c2); // 就是把c2集合的全部数据倒入到c1集合中去。
        System.out.println(c1);
        System.out.println(c2);
    }
}

迭代器遍历集合

image-20240406200844773

接下来学习的迭代器就是一种集合的通用遍历方式。

代码写法如下:

Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");
System.out.println(c); //[赵敏, 小昭, 素素, 灭绝]

//第一步:先获取迭代器对象
//解释:Iterator就是迭代器对象,用于遍历集合的工具)
Iterator<String> it = c.iterator();

//第二步:用于判断当前位置是否有元素可以获取
//解释:hasNext()方法返回true,说明有元素可以获取;反之没有
while(it.hasNext()){
    //第三步:获取当前位置的元素,然后自动指向下一个元素.
    String e = it.next();
    System.out.println(s);
}

迭代器代码的原理如下:

  • 当调用iterator()方法获取迭代器时,当前指向第一个元素
  • hasNext()方法则判断这个位置是否有元素,如果有则返回true,进入循环
  • 调用next()方法获取元素,然后自动指向下一个位置
  • 等下次循环时,则获取下一个元素,依此内推
增强for循环遍历集合

增强for不光可以遍历集合,还可以遍历数组。接下来我们用代码演示一下:

Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");

//1.使用增强for遍历集合
for(String s: c){
    System.out.println(s); 
}

//2.再尝试使用增强for遍历数组
String[] arr = {"迪丽热巴", "古力娜扎", "稀奇哈哈"};
for(String name: arr){
    System.out.println(name);
}
lambda表达式遍历集合

集合的foreach方法结合lambda表达式遍历结合

c.forEach(new Consumer<String>() {
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
由于Consumer是接口,无法实例化对象,所以可以使用匿名内部类,
由于consumer是函数式接口,所以可以使用lambda表达式来简化
package com.itheima.d2_collection_traverse;
import java.util.ArrayList;
import java.util.Collection;

/**
     目标:Collection集合的遍历方式三:JDK8开始新增的Lambda表达式。
 */
public class CollectionDemo03 {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();
        c.add("赵敏");
        c.add("小昭");
        c.add("殷素素");
        c.add("周芷若");
        System.out.println(c);
        // [赵敏, 小昭, 殷素素, 周芷若]
        //                     s

        // default void forEach(Consumer<? super T> action):  结合Lambda表达式遍历集合:
        //        c.forEach(new Consumer<String>() {
        //            @Override
        //            public void accept(String s) {
        //                System.out.println(s);
        //            }
        //        });
        //
        //        c.forEach((String s) -> {
        //                System.out.println(s);
        //        });
        //
        //        c.forEach(s  -> {
        //            System.out.println(s);
        //        });
        //
        //        c.forEach(s  -> System.out.println(s) );

        c.forEach(System.out::println );
    }
}

集合在计算机中的存储原理

当往集合中存对象时,实际上存储的是对象的地址值

image-20240406200851809

List集合

image-20240406200855481

List集合的特有方法

image-20240406200859651

//1.创建一个ArrayList集合对象(有序、有索引、可以重复)
List<String> list = new ArrayList<>();
list.add("蜘蛛精");
list.add("至尊宝");
list.add("至尊宝");
list.add("牛夫人"); 
System.out.println(list); //[蜘蛛精, 至尊宝, 至尊宝, 牛夫人]

//2.public void add(int index, E element): 在某个索引位置插入元素
list.add(2, "紫霞仙子");
System.out.println(list); //[蜘蛛精, 至尊宝, 紫霞仙子, 至尊宝, 牛夫人]

//3.public E remove(int index): 根据索引删除元素, 返回被删除的元素
System.out.println(list.remove(2)); //紫霞仙子
System.out.println(list);//[蜘蛛精, 至尊宝, 至尊宝, 牛夫人]

//4.public E get(int index): 返回集合中指定位置的元素
System.out.println(list.get(3));

//5.public E set(int index, E e): 修改索引位置处的元素,修改后,会返回原数据
System.out.println(list.set(3,"牛魔王")); //牛夫人
System.out.println(list); //[蜘蛛精, 至尊宝, 至尊宝, 牛魔王]

list集合的遍历方式

  • 普通for循环(只因为List有索引)
  • 迭代器
  • 增强for
  • Lambda表达式
package com.itheima.d3_collection_list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
    拓展:List系列集合的遍历方式.

    List遍历方式:
        (1)for循环。(独有的,因为List有索引)。
        (2)迭代器。
        (3)foreach。
        (4)JDK 1.8新技术。

 */
public class ListTest2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("糖宝宝");
        list.add("蜘蛛精");
        list.add("至尊宝");

        //(1)for循环
        for (int i = 0; i < list.size(); i++) {
            // i = 0 1 2
            String s = list.get(i);
            System.out.println(s);
        }

        //(2)迭代器。
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        //(3)增强for循环(foreach遍历)
        for (String s : list) {
            System.out.println(s);
        }

        //(4)JDK 1.8开始之后的Lambda表达式
        list.forEach(s -> {
            System.out.println(s);
        });
    }
}

ArrayList集合

ArrayList集合的底层原理

image-20240406200904881

数组的长度是固定的,但是集合的长度是可变的,这是怎么做到的呢?原理如下:

image-20240406200909789

数组扩容,并不是在原数组上扩容(原数组是不可以扩容的),底层是创建一个新数组,然后把原数组中的元素全部复制到新数组中去。

image-20240406200914191

ArrayList的使用场景 image-20240406200918407

LinkedList集合

LinkedList集合介绍

LinkedList底层是链表结构,链表结构是由一个一个的节点组成,一个节点由数据值、下一个元素的地址组成。如下图所示

image-20240406200930286

假如,现在要在B节点和D节点中间插入一个元素,只需要把B节点指向D节点的地址断掉,重新指向新的节点地址就可以了。如下图所示:

image-20240406200934576

假如,现在想要把D节点删除,只需要让C节点指向E节点的地址,然后把D节点指向E节点的地址断掉。此时D节点就会变成垃圾,会把垃圾回收器清理掉。

image-20240406200940702

上面的链表是单向链表,它的方向是从头节点指向尾节点的,只能从左往右查找元素,这样查询效率比较慢;还有一种链表叫做双向链表,不光可以从做往右找,还可以从右往左找。如下图所示:

image-20240406200944509

LinkedList集合是基于双向链表实现了,所以相对于ArrayList新增了一些可以针对头尾进行操作的方法,如下图示所示:

image-20240406200948039

LinkedList集合的使用场景

设计栈和队列

  • 队列

image-20240406200952064

image-20240406200955974

package com.itheima.d3_collection_list;

import java.util.LinkedList;

/**
 * 目标:掌握LinkedList集合的使用。
 */
public class ListTest3 {
    public static void main(String[] args) {
        // 1、创建一个队列。
        LinkedList<String> queue = new LinkedList<>();
        // 入队
        queue.addLast("第1号人");
        queue.addLast("第2号人");
        queue.addLast("第3号人");
        queue.addLast("第4号人");
        System.out.println(queue);
        // 出队
        System.out.println(queue.removeFirst());
        System.out.println(queue.removeFirst());
        System.out.println(queue.removeFirst());
        System.out.println(queue);
        System.out.println("--------------------------------------------------");
        // 2、创建一个栈对象。
        LinkedList<String> stack = new LinkedList<>();
        // 压栈(push)   实际调用的就是addFirst方法
        stack.push("第1颗子弹");
        stack.push("第2颗子弹");
        stack.push("第3颗子弹");
        stack.push("第4颗子弹");
        System.out.println(stack);
        // 出栈(pop)   实际调用的就是removeFirst方法
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack);
    }
}

Set集合

image-20240406200959580

//Set<Integer> set = new HashSet<>();	//无序、无索引、不重复    [按照哈希算法计算位置输出的]
//Set<Integer> set = new LinkedHashSet<>(); //有序、无索引、不重复    [666, 555, 777, 888]
Set<Integer> set = new TreeSet<>(); //可排序(升序)、无索引、不重复   [555, 666, 777, 888]
set.add(666);
set.add(555);
set.add(555);
set.add(888);
set.add(888);
set.add(777);
set.add(777);
System.out.println(set); //[555, 666, 777, 888]

HashSet集合

HashSet可以存储null值

image-20240418140748110

哈希值

image-20240406201004024

HashSet集合的底层原理(基于HashMap集合)

image-20240406201012563

HashSet集合底层是基于哈希表实现的,哈希表根据JDK版本的不同,也是有点区别的

  • JDK8以前:哈希表 = 数组+链表
  • JDK8以后:哈希表 = 数组+链表+红黑树

image-20240406201016593

我们发现往HashSet集合中存储元素时,底层调用了元素的两个方法:一个是hashCode方法获取元素的hashCode值(哈希值);另一个是调用了元素的equals方法,用来比较新添加的元素和集合中已有的元素是否相同。

  • 只有新添加元素的hashCode值和集合中以后元素的hashCode值相同、新添加的元素调用equals方法和集合中已有元素比较结果为true, 才认为元素重复。
  • 如果hashCode值相同,equals比较不同,则以链表的形式连接在数组的同一个索引为位置(如上图所示)

在JDK8开始后,为了提高性能,当链表的长度超过8时,就会把链表转换为红黑树,如下图所示:

image-20240406201021172

image-20240418103113199

二叉树

image-20240406201024354

二叉排序树

image-20240406201027335

平衡二叉树

image-20240406201030628

红黑树image-20240406201034245

HashSet去重原理

前面我们学习了HashSet存储元素的原理,依赖于两个方法:一个是hashCode方法用来确定在底层数组中存储的位置,另一个是用equals方法判断新添加的元素是否和集合中已有的元素相同。

要想保证在HashSet集合中没有重复元素,我们需要重写元素类的hashCode和equals方法。比如以下面的Student类为例,假设把Student类的对象作为HashSet集合的元素,想要让学生的姓名和年龄相同,就认为元素重复。

public class Student{
    private String name; //姓名
    private int age; //年龄
    private double height; //身高

    //无参数构造方法
    public Student(){}
    //全参数构造方法
    public Student(String name, int age, double height){
        this.name=name;
        this.age=age;
        this.height=height;
    }
    //...get、set、toString()方法自己补上..

    //按快捷键生成hashCode和equals方法
    //alt+insert 选择 hashCode and equals
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        if (Double.compare(student.height, height) != 0) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result;
        long temp;
        result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        temp = Double.doubleToLongBits(height);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }
}

接着,写一个测试类,往HashSet集合中存储Student对象。

public class Test{
    public static void main(String[] args){
        Set<Student> students = new HashSet<>();
        Student s1 = new Student("至尊宝",20, 169.6);
        Student s2 = new Student("蜘蛛精",23, 169.6);
        Student s3 = new Student("蜘蛛精",23, 169.6);
        Student s4 = new Student("牛魔王",48, 169.6);
        
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        
        for(Student s : students){
            System.out.println(s);
        }
    }
}

打印结果如下,我们发现存了两个蜘蛛精,当时实际打印出来只有一个,而且是无序的。

Student{name='牛魔王', age=48, height=169.6}
Student{name='至尊宝', age=20, height=169.6}
Student{name='蜘蛛精', age=23, height=169.6}

LinkedHashSet集合

img

image-20240406201117621

每次添加元素,就和上一个元素用双向链表连接一下。第一个添加的元素是双向链表的头节点,最后一个添加的元素是双向链表的尾节点。

把上个案例中的集合改成LinkedList集合,我们观察效果怎样

public class Test{
    public static void main(String[] args){
        Set<Student> students = new LinkedHashSet<>();
        Student s1 = new Student("至尊宝",20, 169.6);
        Student s2 = new Student("蜘蛛精",23, 169.6);
        Student s3 = new Student("蜘蛛精",23, 169.6);
        Student s4 = new Student("牛魔王",48, 169.6);

        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);

        for(Student s : students){
            System.out.println(s);
        }
    }
}

打印结果如下

Student{name='至尊宝', age=20, height=169.6}
Student{name='蜘蛛精', age=23, height=169.6}
Student{name='牛魔王', age=48, height=169.6}

TreeSet集合

TreeSet不可以存储null值,会报空指针异常

TreeSet集合底层原理基于HashMap集合实现image-20240406201153282

image-20240406201211637

TreeSet自定义排序规则

我们想要告诉TreeSet集合按照指定的规则排序,有两种办法:

第一种:让元素的类实现Comparable接口,重写compareTo方法

第二种:在创建TreeSet集合时,通过构造方法传递Compartor比较器对象

  • 排序方式1:我们先来演示第一种排序方式
//第一步:先让Student类,实现Comparable接口
//注意:Student类的对象是作为TreeSet集合的元素的
public class Student implements Comparable<Student>{
    private String name;
    private int age;
    private double height;
    //无参数构造方法
    public Student(){}
    //全参数构造方法
    public Student(String name, int age, double height){
        this.name=name;
        this.age=age;
        this.height=height;
    }
    //...get、set、toString()方法自己补上..

    //第二步:重写compareTo方法
    //按照年龄进行比较,只需要在方法中让this.age和o.age相减就可以。
    /*
    原理:
    在往TreeSet集合中添加元素时,add方法底层会调用compareTo方法,根据该方法的
    结果是正数、负数、还是零,决定元素放在后面、前面还是不存。
    */
    @Override
    public int compareTo(Student o) {
        //this:表示将要添加进去的Student对象
        //o: 表示集合中已有的Student对象
        return this.age-o.age;
    }
}

此时,再运行测试类,结果如下

Student{name='至尊宝', age=20, height=169.6}
Student{name='紫霞', age=20, height=169.8}
Student{name='蜘蛛精', age=23, height=169.6}
Student{name='牛魔王', age=48, height=169.6}
  • 排序方式2:接下来演示第二种排序方式
//创建TreeSet集合时,传递比较器对象排序
/*
原理:当调用add方法时,底层会先用比较器,根据Comparator的compare方是正数、负数、还是零,决定谁在后,谁在前,谁不存。
*/
//下面代码中是按照学生的年龄升序排序
Set<Student> students = new TreeSet<>(new Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2){
        //需求:按照学生的身高排序
        return Double.compare(o1,o2); 
    }
});

//创建4个Student对象
Student s1 = new Student("至尊宝",20, 169.6);
Student s2 = new Student("紫霞",23, 169.8);
Student s3 = new Student("蜘蛛精",23, 169.6);
Student s4 = new Student("牛魔王",48, 169.6);

//添加Studnet对象到集合
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
System.out.println(students);

image-20240406201247369

不同集合的使用场景

image-20240406201242723

image-20240406201254950

集合的并发修改异常

image-20240406201259707

package com.itheima.d5_collection_exception;
import java.util.*;

/**
 * 目标:理解集合的并发修改异常问题,并解决。
 */
public class CollectionTest1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("王麻子");
        list.add("小李子");
        list.add("李爱花");
        list.add("张全蛋");
        list.add("晓李");
        list.add("李玉刚");
        System.out.println(list);
        //  [王麻子, 小李子, 李爱花, 张全蛋, 晓李, 李玉刚]

        // 需求:找出集合中全部带“李”的名字,并从集合中删除。
//        Iterator<String> it = list.iterator();
//        while (it.hasNext()){
//            String name = it.next();
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);

        // 使用for循环遍历集合并删除集合中带李字的名字
        //  [王麻子, 小李子, 李爱花, 张全蛋, 晓李, 李玉刚]
        //  [王麻子, 李爱花, 张全蛋, 李玉刚]
        //                                i
//        for (int i = 0; i < list.size(); i++) {
//            String name = list.get(i);
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);

        System.out.println("---------------------------------------------------------");
        // 怎么解决呢?
        // 使用for循环遍历集合并删除集合中带李字的名字
        //  [王麻子, 小李子, 李爱花, 张全蛋, 晓李, 李玉刚]
        //  [王麻子, 张全蛋]
        //                  i
//        for (int i = 0; i < list.size(); i++) {
//            String name = list.get(i);
//            if(name.contains("李")){
//                list.remove(name);
//                i--;
//            }
//        }
//        System.out.println(list);
        // 倒着去删除也是可以的。

        // 需求:找出集合中全部带“李”的名字,并从集合中删除。
//        Iterator<String> it = list.iterator();
//        while (it.hasNext()){
//            String name = it.next();
//            if(name.contains("李")){
//                // list.remove(name); // 并发修改异常的错误。
//                it.remove(); // 删除迭代器当前遍历到的数据,每删除一个数据后,相当于也在底层做了i--
//            }
//        }
//        System.out.println(list);

        // 使用增强for循环遍历集合并删除数据,没有办法解决bug.
//        for (String name : list) {
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);

//        list.forEach(name -> {
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        });
//        System.out.println(list);
    }
}

Collections工具类

常用方法

注意Collections并不是集合,它比Collection多了一个s,一般后缀为s的类很多都是工具类。这里的Collections是用来操作Collection的工具类。它提供了一些好用的静态方法,如下
image-20240406201305891

我们把这些方法用代码来演示一下:

public class CollectionsTest{
    public static void main(String[] args){
        //1.public static <T> boolean addAll(Collection<? super T> c, T...e)
        List<String> names = new ArrayList<>();
        Collections.addAll(names, "张三","王五","李四", "张麻子");
        System.out.println(names);

        //2.public static void shuffle(List<?> list):对集合打乱顺序
        Collections.shuffle(names);
        System.out.println(names);

        //3.public static <T> void short(List<T list): 对List集合排序
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(5);
        list.add(2);
        Collections.sort(list);
        System.out.println(list);
    }
}

Collections工具类自定义排序方法

上面我们往集合中存储的元素要么是Stirng类型,要么是Integer类型,他们本来就有一种自然顺序所以可以直接排序。但是如果我们往List集合中存储Student对象,这个时候想要对List集合进行排序自定义比较规则的。指定排序规则有两种方式,如下:

排序方式1:让元素实现Comparable接口,重写compareTo方法

比如现在想要往集合中存储Studdent对象,首先需要准备一个Student类,实现Comparable接口。

public class Student implements Comparable<Student>{
    private String name;
    private int age;
    private double height;

    //排序时:底层会自动调用此方法,this和o表示需要比较的两个对象
    @Override
    public int compareTo(Student o){
        //需求:按照年龄升序排序
        //如果返回正数:说明左边对象的年龄>右边对象的年龄
        //如果返回负数:说明左边对象的年龄<右边对象的年龄,
        //如果返回0:说明左边对象的年龄和右边对象的年龄相同
        return this.age - o.age;
    }

    //...getter、setter、constructor..
}

然后再使用Collections.sort(list集合)对List集合排序,如下:

//3.public static <T> void short(List<T list): 对List集合排序
List<Student> students = new ArrayList<>();
students.add(new Student("蜘蛛精",23,169.7));
students.add(new Student("紫霞",22,169.8));
students.add(new Student("紫霞",22,169.8));
students.add(new Student("至尊宝",26,169.5));

/*
原理:sort方法底层会遍历students集合中的每一个元素,采用排序算法,将任意两个元素两两比较;
    每次比较时,会用一个Student对象调用compareTo方法和另一个Student对象进行比较;
    根据compareTo方法返回的结果是正数、负数,零来决定谁大,谁小,谁相等,重新排序元素的位置
    
    注意:这些都是sort方法底层自动完成的,想要完全理解,必须要懂排序算法才行;
*/
Collections.sort(students); 
System.out.println(students);

排序方式2:使用调用sort方法是,传递比较器

/*
原理:sort方法底层会遍历students集合中的每一个元素,采用排序算法,将任意两个元素两两比较;
    每次比较,会将比较的两个元素传递给Comparator比较器对象的compare方法的两个参数o1和o2,
    根据compare方法的返回结果是正数,负数,或者0来决定谁大,谁小,谁相等,重新排序元素的位置
    
    注意:这些都是sort方法底层自动完成的,不需要我们完全理解,想要理解它必须要懂排序算法才行.
*/
Collections.sort(students, new Comparator<Student>(){
    @Override
    public int compare(Student o1, Student o2){
        return o1.getAge()-o2.getAge();
    }
}); 
System.out.println(students);

斗地主案例

我们先分析一下业务需求:

  • 总共有54张牌,每一张牌有花色和点数两个属性、为了排序还可以再加一个序号
  • 点数可以是:“3”,"4","5","6","7","8","9","10","J","Q","K","A","2"
  • 花色可以是:“♣”,"♠","♥","♦"
  • 斗地主时:三个玩家每人手里17张牌,剩余3张牌作为底牌
第一步:为了表示每一张牌有哪些属性,首先应该新建一个扑克牌的类
第二步:启动游戏时,就应该提前准备好54张牌
第三步:接着再完全洗牌、发牌、捋牌、看牌的业务逻辑

先来完成第一步,定义一个扑克类Card

public class Card {
    private String number;
    private String color;
    // 每张牌是存在大小的。
    private int size; // 0 1 2 ....

    public Card() {
    }

    public Card(String number, String color, int size) {
        this.number = number;
        this.color = color;
        this.size = size;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    @Override
    public String toString() {
        return color + number ;
    }
}

再完成第二步,定义一个房间类,初始化房间时准备好54张牌

public class Room {
    // 必须有一副牌。
    private List<Card> allCards = new ArrayList<>();

    public Room(){
        // 1、做出54张牌,存入到集合allCards
        // a、点数:个数确定了,类型确定。
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        // b、花色:个数确定了,类型确定。
        String[] colors = {"♠", "♥", "♣", "♦"};
        int size = 0; // 表示每张牌的大小
        // c、遍历点数,再遍历花色,组织牌
        for (String number : numbers) {
            // number = "3"
            size++; // 1 2 ....
            for (String color : colors) {
                // 得到一张牌
                Card c = new Card(number, color, size);
                allCards.add(c); // 存入了牌
            }
        }
        // 单独存入小大王的。
        Card c1 = new Card("",  "

标签:Java,String,System,003,println,new,public,out
From: https://www.cnblogs.com/kk-koala/p/18328613

相关文章

  • Java入门
    day1入门常见的CMD命令打开cmd:win+R输入CMD按下回车键打开我的电脑:win+E盘符名称+冒号说明:盘符切换举例:E:(冒号为英文输入法)回车,表示切换到E盘dir说明:查看当前路径下的所有内容(该文件夹下的所有内容)cd目录说明:进入单级目录举例:cditheima特别说明:itheima(过长......
  • Java基础12:JavaDoc生成文档
    1.简介JavaDoc是一种将注释生成HTML文档的技术,生成的HTML文档类似于Java的API,易读且清晰明了。在简略介绍JavaDoc写法之后,再看一下在IntellijIdea中如何将代码中的注释生成HTML文档。JavaDoc是Sun公司提供的一个技术,它从程序源代码中抽取类、方法、成员等注释形成一个和源代......
  • Java-002
    final关键字final关键字是最终的意思,可以修饰(类、方法、变量)修饰类:该类被称为最终类,特点是不能被继承了。修饰方法:该方法被称为最终方法,特点是不能被重写了。修饰变量:该变量只能被赋值一次。final修饰的变量必须赋值,要么在定义时赋值,要么在构造器中赋值final修饰变量的注意......
  • Java-001
    Java入门IDEA优化idea插件翻译、阿里巴巴代码规范指导IDEAdebug使用Stepinto:单步执行(一行一行代码执行),如果遇到子函数,就会进入子函数,并且继续单步执行。就是每一行需要执行的代码都不跳过,一行一行进行。Stepover:在单步执行的时候,如果遇到子函数,并不会进入子函数,而是......
  • Java基础11:包机制
    包机制1.问题发现存在这样一个问题:当定义了多个类的时候,可能会发生类名的重复问题。解决方式:在java中采用包机制处理开发者定义的类名冲突问题。就好比我们平时的用电脑,一个文件夹下不能存在同名的文件,我们要是有这样的需求,但是又不想换名字,我们就可以考虑使用新建一个文件......
  • Java基础10:拓展运算符、字符串连接符、三元运算符
    扩展运算符publicstaticvoidmain(String[]args){ inta=10; intb=20; a+=b;//a=a+b System.out.println(a+":"+b);}字符串连接符"+"运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接。//字符串......
  • java-01
    Java入门IDEA优化idea插件翻译、阿里巴巴代码规范指导IDEAdebug使用Stepinto:单步执行(一行一行代码执行),如果遇到子函数,就会进入子函数,并且继续单步执行。就是每一行需要执行的代码都不跳过,一行一行进行。Stepover:在单步执行的时候,如果遇到子函数,并不会进入子函数,而是......
  • Java基础09:逻辑运算符、位运算符
    逻辑运算符逻辑与:&&和&,逻辑或:||和|,逻辑非:!。publicstaticvoidmain(String[]args){ booleana=true; booleanb=false; System.out.println("a&&b="+(a&&b));//false System.out.println("a||b="+(a||b));......
  • django学习入门系列之第五点《javascript的条件语句和函数》
    文章目录5.6条件语句5.7函数往期回顾5.6条件语句if(){}elseif(){}5.7函数#python中函数定义的格式deffunc{函数的内容}#使用函数func()//javascript函数中的内容functionfunc(){函数的内容}//使用函数func()往......
  • Java基础07:基本运算符
    运算符运算符operatorJava语言支持如下运算符:算术运算符:+,-,*,/,%,++,--赋值运算符=关系运算符:>,<,>=,<=,==,!=instanceof逻辑运算符:&&,||,!位运算符:&,|,^,~,>>,<<,>>>(了解!!!)条件运算符?:扩展赋值运算符:+=,-=,*=,/=二元运算符publicstaticvoidmain(Str......