java 面对对象和io流的一道题不会做

面向对象设计一副扑克,
(类似斗地主游戏起始时)
实现随机等分成三份,并剩三张牌。
1-将这四份牌分别序列化到文件中
2-从文件中反序列化分别输出这四份牌。

最简单粗暴的方法就是:先生成一个Arraylist扑克顺序集合,通过for循环循环N-1次,内部通过生成随机数,进行调换数组位置,最终胜出一个完全打乱顺序的扑克。
然后分发给三个扑克数组,最后三张牌一个数组,然后通过ObjectOutputStream进行序列化和反序列化。
这种洗牌每次都将集合重新排序,如果你会链表,建议用双向链表来实现洗牌。

  • 扑克牌实体类
package com.zpecs.poker.entity;

import java.io.Serializable;

/**
 * \扑克牌
 * 
 * @author Administrator
 *
 */
public class Poker implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private Type type;// 牌型
    private String code;// 牌号

    public Poker() {
        super();
    }

    public Poker(Type type, String code) {
        super();
        this.type = type;
        this.code = code;
    }

    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((code == null) ? 0 : code.hashCode());
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Poker other = (Poker) obj;
        if (code == null) {
            if (other.code != null)
                return false;
        } else if (!code.equals(other.code))
            return false;
        if (type != other.type)
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Poker [type=" + type + ", code=" + code + "]";
    }

    public enum Type {
        RED("01", "红心"), SQUARE("02", "方块"), SPEADES("03", "黑桃"), BLOSSOM("04", "梅花");
        private String type;
        private String name;

        private Type(String type, String name) {
            this.type = type;
            this.name = name;
        }

        public String getType() {
            return type;
        }

        public String getName() {
            return name;
        }
    }

}

  • 工具类
package com.zpecs.poker.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;

import com.zpecs.poker.entity.Poker;
import com.zpecs.poker.entity.Poker.Type;

/**
 * \枚举,保证单例
 * 
 * @author Administrator
 *
 */
public enum PokerUtil {
    INSTANCE;
    private static List<Poker> pokers = new ArrayList<>(54);
    private static String[] codes = new String[] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
    private static Random random = new Random();
    // 初始化54张牌,这样效率比较高
    static {
        pokers.add(new Poker(null, "小王"));// 添加小王
        pokers.add(new Poker(null, "大王"));// 添加大王
        for (Type type : Type.values()) {// 添加其他52张牌
            for (String code : codes) {
                pokers.add(new Poker(type, code));
            }
        }
    }

    /**
     * \生成4副牌,前三副是均分,最后一幅底牌
     * 
     * @return
     */
    public Map<String, Set<Poker>> generator() {
        List<Poker> pokers = new ArrayList<>(PokerUtil.pokers);
        Map<String, Set<Poker>> map = new HashMap<String, Set<Poker>>(4);
        for (int i = 0; i < 3; i++) {// 生成3副等数牌
            Set<Poker> set = new HashSet<>();
            while (set.size() < 17) {
                Poker poker = generatorPoker(pokers);// 获取一张牌
                set.add(poker);// 添加到散列表里面
                pokers.remove(poker);// 从临时牌集合移除已生成的牌
            }
            map.put(UUID.randomUUID().toString(), set);
        }
        // 临时表剩余的牌即为底牌
        map.put("底牌", new HashSet<>(pokers));
        return map;
    }

    /**
     * \生成一张牌
     * 
     * @return
     */
    private Poker generatorPoker(List<Poker> pokers) {
        return pokers.get(random.nextInt(pokers.size()));
    }

    /**
     * \将牌序列化到文件
     * 
     * @param path 文件路径
     * @param map  牌
     */
    public void serialize(String path, Map<String, Set<Poker>> map) {
        File file = new File(path);
        if (file.exists()) {// 如果文件存在,删除文件
            file.delete();
        }
        try {
            file.createNewFile();// 创建一个干净文件
        } catch (IOException e1) {
            e1.printStackTrace();
            throw new RuntimeException(e1);
        }
        try (FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos);) {// try-with语句,1.8新特性,不需要手动关闭io流
            oos.writeObject(map);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * \反序列化
     * 
     * @param path
     */
    public Object unserialize(String path) {
        File file = new File(path);
        if (!file.exists()) {
            throw new RuntimeException("文件不存在");
        }
        try (FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis)) {
            return ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    // 测试
    public static void main(String[] args) {
        Map<String, Set<Poker>> map = PokerUtil.INSTANCE.generator();
        // 打印牌
        System.out.println(map);
        // 循环打印牌,看的更清晰
        map.forEach((k, v) -> {
            System.out.println("----------人[" + k + "]----------");
            v.forEach(p -> {
                System.out.println(p);
            });
        });
        // 写入文件
        PokerUtil.INSTANCE.serialize("D:/test.txt", map);
        // 从文件读入
        Map<String, Set<Poker>> map2 = (Map<String, Set<Poker>>) PokerUtil.INSTANCE.unserialize("D:test.txt");
        // 打印牌
        System.out.println(map2);
        map2.forEach((k, v) -> {
            System.out.println("----------人[" + k + "]----------");
            v.forEach(p -> {
                System.out.println(p);
            });
        });
    }
}

  • 注:使用的是jdk1.8,请在jdk1.8环境下运行