基于ArrayList实现简单洗牌

前言

在之前的那篇文章中,我们已经认识了顺序表—>http://t.csdnimg.cn/2I3fE

基于此,便好理解ArrayList和后面的洗牌游戏了。

什么是ArrayList?

 ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表,与普通数组的区别就是它是没有固定大小的限制。

ArrayList的一些常见操作

首先我们要导入一个ArrayList包

import java.util.ArrayList;

在正式调用方法之前,别忘了创建一个ArrayList对象哦~

ArrayList<String> list = new ArrayList<>();

在这里,我就创建了一个只能存储String类型数据的ArrayList(顺序表)

下面便是ArrayList一些常见的使用方法,仔细观察就不难发现这些方法在模拟实现顺序表的时候就已经实现过了,现在直接用就行了,若有不记得了,可查看帮助手册-->Overview (Java SE 17 & JDK 17)

import java.util.ArrayList;public class commonTest {public static void main(String[] args) {// 创建一个ArrayList并添加一些元素ArrayList<String> list = new ArrayList<>();list.add("apple");list.add("banana");list.add("orange");// 使用get方法获取指定位置的元素String fruit = list.get(1);System.out.println("下标为1的水果是: " + fruit);// 使用set方法替换指定位置的元素list.set(0, "hello");System.out.println("替换之后 " + list);// 使用remove方法移除指定位置的元素list.remove(2);System.out.println("移除之后 " + list);// 使用size方法获取列表大小int size = list.size();System.out.println("列表大小: " + size);// 使用contains方法判断列表是否包含指定元素boolean containsBanana = list.contains("banana");System.out.println("是否包含banana " + containsBanana);}}

运行结果如图


运用之实现简单洗牌

纸牌相信大家都接触过,来看看如何利用ArrayList去实现洗牌?

这才是本文的重点哦~理论最终还是要服务与实践的,接下来就由我来带着各位看官来实现吧~

首先思考:

要洗牌,首先要有牌,想要表示出来,那么便要想好牌的属性--->花色和数字,好,那么就可以定义一个Card类专门存储这个,看下图:

public class Card {public int rank; // 表示牌面的数字public String suit; // 表示花色// 构造方法,用于初始化牌的数字和花色public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}// 重写toString()方法,以便打印Card对象时能够直观地展示牌的信息@Overridepublic String toString() {return "Card{" + suit + "  " + rank + "}";}
}

这样一来,这个Card类很好地封装了扑克牌的属性。

一张牌肯定不够,一副牌有52张(去掉大小王)---4个花色,1到13的数字,在洗牌之前,先有一副完整的牌才行显示出来才行

于是就新定义一个Cards类,规定好牌的花色

public static final String[] suits = {"♥", "♠", "♣", "♦"};//定义四种花色

还记得final 的作用吗?这里用final 修饰就是为了不被修改

接着通过两个循环,一个遍历花色,一个遍历数字 ,这样一张新牌就创建好了,别忘了要创建存放牌的List,这里就导入了ArrayList包以便用add方法了。

import java.util.ArrayList;
import java.util.List;
// 买一副牌
public List<Card> buyCards() {List<Card> cardList = new ArrayList<>(); // 基于ArrayList创建一个用于存放牌的Listfor (int i = 0; i < 4; i++) { // 循环四种花色for (int j = 0; j < 13; j++) { // 循环13个数字(2-10,J,Q,K,A)int rank = j; // 当前数字String suit = suits[i]; // 当前花色Card card = new Card(rank, suit); // 创建一张新的牌对象cardList.add(card); // 将新牌加入到牌组中}}return cardList; // 返回完整的一副牌
}

此时运行便是这个样子

这下牌有了那就开始洗牌了,洗牌肯定讲究随机,讲到随机少不了Random方法,要调用它,也到导入对应的Random包。将生成的随机数对应的牌(看索引)在遍历的过程中与每个牌的位置进行交换,这样便完成了洗牌,配合代码食用效果更佳~

import java.util.Random;
// 洗牌
public void shuffle(List<Card> cardList) {Random random = new Random(); // 创建一个随机数生成器for (int i = cardList.size(); i > 0; i--) { // 从最后一张牌开始向前遍历int index = random.nextInt(i); // 生成一个随机的索引swap(cardList, i - 1, index); // 将当前牌与随机选出的牌进行交换}
}// 洗牌的原理-交换
public void swap(List<Card> cardList, int i, int j) {Card tmp = cardList.get(i); // 临时保存第i张牌cardList.set(i, cardList.get(j)); // 将第i张牌替换为第j张牌cardList.set(j, tmp); // 将第j张牌替换为临时保存的牌
}

还记得set方法是干嘛的吗?--->替换指定位置的元素,常见的记住可以提高效率的

此时效果是这样的 

那么到此牌洗好了,那就开始发牌,假设我们有三个人打牌,为了方便展示,就每人抽4张牌,思考一下,拿到牌后是不是也要存储才是?于是便要创建3个List去接受摸到的牌

// 发牌,三个人,每个人轮流摸4
public void drawCard(List<Card> cardList) {List<Card> hand1 = new ArrayList<>(); // 第一个人的手牌List<Card> hand2 = new ArrayList<>(); // 第二个人的手牌List<Card> hand3 = new ArrayList<>(); // 第三个人的手牌List<List<Card>> hand = new ArrayList<>(); // 存放三个人的手牌列表hand.add(hand1);hand.add(hand2);hand.add(hand3);for (int i = 0; i < 4; i++) { // 每个人轮流摸4张牌for (int j = 0; j < 3; j++) { // 三个人依次摸牌Card card = cardList.remove(0); // 从牌组中抽取一张牌,并从原来的牌组中移除hand.get(j).add(card); // 将抽取的牌加入到对应人的手牌列表中}}// 打印每个人摸到的牌System.out.println("第1个人摸到的牌:" + hand1);System.out.println("第2个人摸到的牌:" + hand2);System.out.println("第3个人摸到的牌:" + hand3);}

开始摸牌,用嵌套循环去模拟分发,这里要明白为啥每次只remove(0),这是因为存储牌的也是是基于ArrayList的List,每次移除第一个元素,后续的元素会自动补上,这样一来,每次遍历,下标为0的元素就是原来的下一张牌,就很好地模拟了实际的摸牌体验,

当然,循环停止后,也可以打印剩下的牌

        System.out.println("剩余的牌");//显示剩余的牌System.out.println(cardList);

 最后在创建一个测试类来看看效果是否符合预期

import java.util.List;public class demo {public static void main(String[] args) {Cards cards=new Cards();List<Card> cardList=cards.buyCards();System.out.println("刚开始的牌"+cardList);cards.shuffle(cardList);System.out.println("洗牌之后"+cardList);cards.drawCard(cardList);//摸牌}
}

最后的效果便是这般

说到这里,简单的洗牌游戏就被成功实现啦,如果感觉文章对你有所帮助的话,还请点点赞~

期待我们下次相会😉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/297846.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二十三章 Git

一、Git Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同&#xff0c;它采用了分布式版…

YOLOv8 UI界面设计+热力图显示

进入可视化设计界面&#xff0c;设计UI pyside6-designer 设计好UI保存&#xff0c;然后通过以下命令将ui文件保存为py pyside6-uic myui.ui > myui.py 通过以下命令将资源文件qrc保存为py pyside6-rcc my_rc.qrc > my_rc.py 写主窗口函数实现功能... 项目基于yol…

【STL】vector的底层原理及其实现

vector的介绍 vector是一个可变的数组序列容器。 1.vector的底层实际上就是一个数组。因此vector也可以采用连续存储空间来存储元素。也可以直接用下标访问vector的元素。我们完全可以把它就当成一个自定义类型的数组使用。 2.除了可以直接用下标访问元素&#xff0c;vector还…

Redis缓存穿透和缓存雪崩

一、缓存穿透 1 什么是缓存穿透 缓存穿透说简单点就是大量请求的 key 根本不存在于缓存中&#xff0c;导致请求直接到了数据库上&#xff0c;根本没有经过缓存这一层。举个例子&#xff1a;某个黑客故意制造我们缓存中不存在的 key 发起大量请求&#xff0c;导致大量请求落到数…

Spoon Taking Problem(c++题解)

题目描述 &#xfffd;N 人が円卓に座っており&#xff0c;各人は反時計回りに順に 1, …, &#xfffd;1, …, N と番号付けられています&#xff0e;各人はそれぞれ左右どちらか一方の利き手を持っています&#xff0e; 円卓上には 1, …, &#xfffd;1, …, N と番号付け…

Golang Gin框架

1、这篇文章我们简要讨论一些Gin框架 主要是给大家一个基本概念 1、Gin主要是分为路由和中间件部分。 Gin底层使用的是net/http的逻辑&#xff0c;net/http主要是说&#xff0c;当来一个网络请求时&#xff0c;go func开启另一个协程去处理后续(类似epoll)。 然后主协程持续…

Vue 样式技巧总结与整理[中级局]

SFC&#xff08;单文件组件&#xff09;由 3 个不同的实体组成&#xff1a;模板、脚本和样式。三者都很重要&#xff0c;但后者往往被忽视&#xff0c;即使它可能变得复杂&#xff0c;且经常导致挫折和 bug。 更好的理解可以改善代码审查并减少调试时间。 这里有 7 个奇技淫巧…

VB 通过COM接口解析PSD文件

最近有PS测评的需求&#xff0c;故而想到了解析psd文件&#xff0c;目的就是为了获取文档信息和图层信息&#xff1b;获取PS的图像信息有很多方式&#xff0c;有过程性的&#xff0c;比如监听PS的各种操作事件&#xff1b;有结果性的&#xff0c;比如本文写的解析PSD文件。 0.…

【算法练习】28:选择排序学习笔记

一、选择排序的算法思想 弄懂选择排序算法&#xff0c;先得知道两个概念&#xff1a;未排序序列&#xff0c;已排序序列。 原理&#xff1a;以升序为例&#xff0c;选择排序算法的思想是&#xff0c;先将整个序列当做未排序的序列&#xff0c;以序列的第一个元素开始。然后从左…

libusb Qt使用记录

1.libusb 下载 &#xff0c;选择编译好的二进制文件&#xff0c;libusb-1.0.26-binaries.7z libusb Activity 2. 解压 3. 在 Qt Widgets Application 或者 Qt Console Application 工程中导入库&#xff0c;Qt 使用的是 minggw 64编译器&#xff0c;所以选择libusb-MinGW-x64。…

Kubernetes(k8s):精通 Pod 操作的关键命令

Kubernetes&#xff08;k8s&#xff09;&#xff1a;精通 Pod 操作的关键命令 1、查看 Pod 列表2、 查看 Pod 的详细信息3、创建 Pod4、删除 Pod5、获取 Pod 日志6、进入 Pod 执行命令7、暂停和启动 Pod8、改变 Pod 副本数量9、查看当前部署中使用的镜像版本10、滚动更新 Pod11…

保研线性代数复习3

一.基底&#xff08;Basis&#xff09; 1.什么是生成集&#xff08;Generating Set&#xff09;&#xff1f;什么是张成空间&#xff08;Span&#xff09;&#xff1f; 存在向量空间V(V&#xff0c;&#xff0c;*)&#xff0c;和向量集&#xff08;xi是所说的列向量&#xff…

集合/容器

集合概念 当我们保存一组一样(类型相同)的元素时候&#xff0c;我们应该使用一个容器来存储&#xff0c;就可以采用数组&#xff0c;但是数组存在以下缺点&#xff1a; 1、长度开始时必须指定&#xff0c;一旦指定就不能更改。 2、使用数组进行增加元素的步骤比较麻烦 这时候…

深入PostgreSQL中的pg_global表空间

pg_global表空间的位置 在PG当中&#xff0c;一个实例(cluster)初始化完以后&#xff0c;你会看到有下边两个与表空间相关的目录生成&#xff1a; $PGDATA/base $PGDATA/global 我们再用元命令\db以及相关视图看看相应的表空间信息&#xff1a; postgres# \db …

Golang | Leetcode Golang题解之第10题正则表达式匹配

题目&#xff1a; 题解&#xff1a; func isMatch(s string, p string) bool {m, n : len(s), len(p)matches : func(i, j int) bool {if i 0 {return false}if p[j-1] . {return true}return s[i-1] p[j-1]}f : make([][]bool, m 1)for i : 0; i < len(f); i {f[i] m…

重构智能防丢产品,苹果Find My技术引领市场发展

目前市场上最主要的防丢技术是蓝牙防丢和GPS防丢&#xff0c;蓝牙防丢是通过感应防丢器与绑定手机的距离来实现防丢的。一般防丢会默认设置一个最远安全距离&#xff0c;超过这个安全距离后&#xff0c;与手机蓝牙信号断开&#xff0c;触发防丢报警&#xff0c;用户根据防丢报警…

JS详解-手写Promise!!!

前言&#xff1a; 针对js的深入理解&#xff0c;作者学习并撰写以下文章&#xff0c;由于理解认知有限难免存在偏差&#xff0c;请大家指正&#xff01;所有定义来自mdn。 Promise介绍&#xff1a; 对象表示异步操作最终的完成&#xff08;或失败&#xff09;以及其结果值. 描…

设计模式 --5观察者模式

观察者模式 观察者模式的优缺点 优点 当一个对象改变的时候 需要同时改变其他对象的相关动作的时候 &#xff0c;而且它不知道有多少具体的对象需要改变 应该考虑使用观察者模式 。观察者模式的工作就是解除耦合 让耦合双方都依赖与抽象 而不是具体 是的各自改变都不会影响另…

Leetcode_2两数相加

文章目录 前言一、两数相加1.1 问题描述1.2 解法一&#xff1a;分别将链表转为数字&#xff0c;然后相加1.3 代码实现1.4 解法二&#xff1a;分别将对应位置数字相加1.5 代码实现 二、使用步骤1.引入库2.读入数据 前言 链表是一种物理内存非连续存储&#xff0c;非顺序的线性数…

golang 和java对比的优劣势

Golang&#xff08;或称Go&#xff09;和Java都是非常流行的编程语言&#xff0c;被广泛应用于各种领域的软件开发。尽管它们都是高级编程语言&#xff0c;但它们具有许多不同的特性和适用场景。本文将重点比较Golang和Java&#xff0c;探讨它们的优势和劣势。 性能方面&#…