[Java学习日记]IO流练习

目录

一.制造假数据:生成假姓名并写到文件当中 

二.使用Hutool工具一次性获取网页内容

三.带权重的随机点名器

四.properties配置文件

五.拼图小游戏完善


一.制造假数据:生成假姓名并写到文件当中 

1.把网址上面爬到到一行行数据拼接成字符串的具体步骤?
2.正则表达式:需要表示字符时一定需要把字符用[]包裹吗?
3.有什么方法可以表示后面跟着逗号或者句号?
4.又有哪些方法表示只取前面的那部分?
5.如何在截取字符串中符合正则表达式的字串的时候只截取分组?
6.如何把集合中的部分数据取出删除(快速方法)?
7.把数组变成List再使用加入集合(快速方法)?
8.如何使自己创造的集合数据(如姓名)不重复?
public class Demo301 {
    final static String FILE_STRING = "D:\\IDEACode\\demo1\\JAVA基础\\src\\Day30_IOPractice\\MyText\\name.txt";
    final static String WEB_STRING1 = "https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0";
    final static String WEB_STRING2 = "http://www.haoming8.cn/baobao/10881.html";
    final static String WEB_STRING3 = "http://www.haoming8.cn/baobao/7641.html";

    public static void main(String[] args) throws IOException {
        //获取数据网址数据,方法一:爬取数据:把网址上面爬到到一行行数据拼接成字符串
        System.out.println("1.重要步骤有:获取URL对象,连接网址");
        System.out.println("读取数据,通过连接获得输入流->转换流->字符缓冲流");

        String familyNameStr = webCrawler(WEB_STRING1);
        String boyNameStr = webCrawler(WEB_STRING2);
        String girlNameStr = webCrawler(WEB_STRING3);

        System.out.println("2.字符不一定非要用[]括起来,直接写上去即可");
        System.out.println("3.可以用(,|。)或者[,。]去代表后面跟的字符(虽然搜索范围变大很多)");
        System.out.println(" 4.?<=忽略前面的内容,?=忽略掉后面的内容,也可以分组取出用()框起来的部分");
        System.out.println("方法中传入第三个参数代表取第几组:可以去除不需要的组");
        System.out.println("5.在matcher匹配到字符串之后,使用group方法获取特定组的数据");

        ArrayList<String> familyNameTempList = getData(familyNameStr, "(....)[,。]", 1);
        ArrayList<String> boyNameTempList = getData(boyNameStr, "(<p>)((..、)*.{2}。)(</p>)", 2);
        ArrayList<String> girlNameTempList = getData(girlNameStr, "(<p>)((.. )*.{2})(</p>)", 2);

        //处理数据
        ArrayList<String> familyNameList = new ArrayList<>();
        ArrayList<String> boyNameList = new ArrayList<>();
        ArrayList<String> girlNameList = new ArrayList<>();
        for (String s : familyNameTempList)
            for (int i = 0; i < s.length(); i++)
                familyNameList.add(s.charAt(i) + "");

        System.out.println("6.IDEA提示方法:使用subList方法分离数据,然后使用clear方法清除这一部分数据");
        familyNameList.subList(familyNameList.size() - 4, familyNameList.size()).clear();

        for (String[] strings : boyNameTempList.stream().map(s -> s.replace("。", ""))
                .map(s -> s.split("、")).collect(Collectors.toList()))
            boyNameList.addAll(Arrays.asList(strings));
        System.out.println("IDEA提示方法:使用Arrays工具类的asList把数组变成集合,再使用List中的addAll方法全部加入");
        for (String[] strings : girlNameTempList.stream().map(s -> s.split("\\s")).collect(Collectors.toList()))
            girlNameList.addAll(Arrays.asList(strings));

        //生成数据
        System.out.println("8.姓名不重复怎么整??使用HashSet作为姓名容器即可");
        ArrayList<String> arrayList = getInfos(familyNameList, boyNameList, girlNameList, 20, 20);
        Collections.shuffle(arrayList);
        BufferedWriter bf = new BufferedWriter(new FileWriter(FILE_STRING));
        for (String s : arrayList) {
            bf.write(s);
            bf.newLine();
        }
        bf.close();
    }

    //方法一:爬取数据:把网址上面爬到到一行行数据拼接成字符串
    public static String webCrawler(String net) throws IOException {
        StringBuilder sb = new StringBuilder();
        //1.获取URL对象,连接网址
        URL url = new URL(net);
        URLConnection conn = url.openConnection();
        //1.读取数据,通过连接获得输入流->转换流->字符缓冲流
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
            sb.append("\n");
        }
        br.close();
        return sb.toString();
    }

    //方法二:初步处理爬取到的数据:得到大部分有用的数据
    private static ArrayList<String> getData(String str, String regex, int index) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        //5.在matcher匹配到字符串之后,使用group方法获取特定组的数据
        ArrayList<String> arrayList = new ArrayList<>();
        while (matcher.find()) arrayList.add(matcher.group(index));
        return arrayList;
    }

    //方法三:传入男生个数,女生个数,获取随机男生女生信息:随机姓名-性别-随机年龄
    public static ArrayList<String> getInfos(ArrayList<String> familyNameList, ArrayList<String> boyNameList, ArrayList<String> girlNameList,
                                             int boyCount, int girlCount) {
        Random random = new Random();
        ArrayList<String> arrayList = new ArrayList<>();
        //使用HashSet使数据不重复
        HashSet<String> boyHashSet = new HashSet<>();
        HashSet<String> girlHashSet = new HashSet<>();
        //这里原本是写了一个拼接姓名方法,简化了
        while (boyHashSet.size() < boyCount)
            boyHashSet.add(familyNameList.get(random.nextInt(familyNameList.size())) + boyNameList.get(random.nextInt(boyNameList.size())));
        while (girlHashSet.size() < girlCount)
            girlHashSet.add(familyNameList.get(random.nextInt(familyNameList.size())) + girlNameList.get(random.nextInt(girlNameList.size())));
        //能写一行就写一行了,不用再去定义SJ一个一个加,也简化了
        for (String s : boyHashSet) arrayList.add(s + "-男-" + random.nextInt(16, 28));
        for (String s : girlHashSet) arrayList.add(s + "-女-" + random.nextInt(16, 28));
        return arrayList;
    }
}

 


二.使用Hutool工具一次性获取网页内容

public class Demo302 {
    public static void main(String[] args) {
        System.out.println("1.使用HttpUtil的get方法获取所有的网页源代码");
        String str = HttpUtil.get(Demo301.WEB_STRING1);
        System.out.println("2.使用ReUtil中的findAll方法传入regex,string,组号即可获取相应的字符串集合");
        List<String> familyNameTempList = ReUtil.findAll("(....)[,。]",str,1);
        System.out.println("3.糊涂包生成的文件会相对于class文件生成:存在out文件中,需要补全路径");
        FileUtil.writeLines(familyNameTempList,Demo301.FILE_STRING,"UTF-8");
    }
}


三.带权重的随机点名器

具体实现步骤使怎样的呢?
//准备数据部分:每行数据加-1
public class Demo303 {
    final static String FILE_STRING2 = "D:\\IDEACode\\demo1\\JAVA基础\\src\\Day30_IOPractice\\MyText\\name2.txt";
    public static void main(String[] args) throws IOException{
        File file = new File(Demo301.FILE_STRING);
        File file2 = new File(FILE_STRING2);
        List<String> list = new ArrayList<>();
        FileUtil.readUtf8Lines(file, list);
        list = list.stream().map(s -> s + "-1").collect(Collectors.toList());
        FileUtil.writeUtf8Lines(list, file2);
    }
}

public class Demo304 {
    public static void main(String[] args) {
        File file = new File(Demo303.FILE_STRING2);
        List<String> list = new ArrayList<>();
        FileUtil.readUtf8Lines(file, list);
        System.out.println("1.用学生类接收不同类型的数据");
        List<Student> students = new ArrayList<>();
        for (String[] strings : list.stream().map(s -> s.split("-")).collect(Collectors.toList()))
            students.add(new Student(strings[0], strings[1], Integer.parseInt(strings[2]), Double.parseDouble(strings[3])));
        System.out.println("2.计算权重总和");
        double weight = 0;
        for (Student student : students)
            weight += student.getWeight();
        System.out.println("3.计算每一个人的实际比重");
        double[] arr = new double[list.size()];
        for (int i = 0; i < students.size(); i++)
            arr[i] = students.get(i).getWeight() / weight;
        System.out.println("4.计算每一个人的权重范围:为了更方便的使用随机生成的数据");
        for (int i = 1; i < arr.length; i++)
            arr[i] = arr[i] + arr[i - 1];
        System.out.println("5.随机抽取,使用二分查找搜索数据");
        double num = Math.random();
        int index = -Arrays.binarySearch(arr, num) - 1;
        System.out.println("6.修改数据");
        Student student = students.get(index);
        student.setWeight(student.getWeight() / 2);
        System.out.println("7.重新写文件,这里的toString方法已经转成对应的格式");
        list = students.stream().map(Student::toString).collect(Collectors.toList());
        FileUtil.writeUtf8Lines(list,file);
    }
}

 


四.properties配置文件

1.properties配置文件的两个特点?
1.后缀名为properties
2.以键值对的形式存储

2.在Java中,Properties是一个什么样的类呢?
为Map的一个实现类,继承于HashTable

3.Properties类里面有什么特别的方法?
里面有特有方法store()可以把数据按照键值对的形式写到配置文件中,load()能够读取数据转换成集合

4.定义Properties时需要限定泛型吗?

5. 使用store方法与load方法时分别需要传入什么参数?
public class Demo305 {
    final static String File_String = "D:\\IDEACode\\demo1\\JAVA基础\\src\\Day30_IOPractice\\MyProperties\\a.properties";
    public static void main(String[] args) throws IOException {
        System.out.println("4.定义Properties不需要说明泛型,可以添加任意数据类型,默认为Object,一般只添加字符串");
        Properties properties = new Properties();
        properties.put("aaa","111");
        properties.put("bbb","222");
        properties.put("ccc","333");
        properties.put("ddd","444");
        System.out.println("5.使用store方法时需要传入字符输出流与备注,使用load方法时需要传入字符输入流");
        properties.store(new FileWriter(File_String), "myProperties");
        properties.clear();
        properties.load(new FileReader(File_String));
        System.out.println(properties);
    }
}


五.拼图小游戏完善

新增的代码(按序号展示)

14.加入存档读档功能:新增JM与JB(定义在最外层的static代码中),吧JB全部加上监听
    private static JMenuItem saveItem1, saveItem2, saveItem3, loadItem1, loadItem2, loadItem3;
    private static JMenu saveMenu, loadMenu;

        saveMenu = new JMenu("存档");
        loadMenu = new JMenu("读档");

        saveItem1 = new JMenuItem("存档1(空)");
        saveItem2 = new JMenuItem("存档2(空)");
        saveItem3 = new JMenuItem("存档3(空)");
        loadItem1 = new JMenuItem("读档1(空)");
        loadItem2 = new JMenuItem("读档2(空)");
        loadItem3 = new JMenuItem("读档3(空)");

        functionMenu.add(saveMenu);
        functionMenu.add(loadMenu);

        saveMenu.add(saveItem1);
        saveMenu.add(saveItem2);
        saveMenu.add(saveItem3);
        loadMenu.add(loadItem1);
        loadMenu.add(loadItem2);
        loadMenu.add(loadItem3);

        saveItem1.addActionListener(this);
        saveItem2.addActionListener(this);
        saveItem3.addActionListener(this);
        loadItem1.addActionListener(this);
        loadItem2.addActionListener(this);
        loadItem3.addActionListener(this);
15.存档需要存储数据:把数据序列化:需要路径,步数,空白位置,图片位置,包装成一个类:并实现Serializable接口
public class GameInfo implements Serializable {
    @Serial
    private static final long serialVersionUID = 7497887490544158029L;
    private int[][] data;
    private int x,y;
    private String path;
    private int step;
    public GameInfo() {
    }
    public GameInfo(int[][] data, int x, int y, String path, int step) {
        this.data = data;
        this.x = x;
        this.y = y;
        this.path = path;
        this.step = step;
    }
    public int[][] getData() {
        return data;
    }
    public void setData(int[][] data) {
        this.data = data;
    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    public String getPath() {
        return path;
    }
    public void setPath(String path) {
        this.path = path;
    }
    public int getStep() {
        return step;
    }
    public void setStep(int step) {
        this.step = step;
    }
    public String toString() {
        return "GameInfo{data = " + data + ", x = " + x + ", y = " + y + ", path = " + path + ", step = " + step + "}";
    }
}
16.完成存档读档功能,需要注意存档文件的名字,修改界面上的存读档文字
    //ActionListener
    @Override
    public void actionPerformed(ActionEvent e) {
        Object o = e.getSource();
        if (o == saveItem1 || o == saveItem2 || o == saveItem3) {
            System.out.println("存档");
            //要写什么数据呢?1.图片路径2.xy3.数组4.步数
            //要如何根据点击的组件建立不同的文件呢?使用组件的getText方法
            JMenuItem jmi = (JMenuItem) o;
            String text = jmi.getText();
            //下面的语句只能trycatch:父类中方法中没有抛出异常,子类也不行
            try (ObjectOutputStream oos = new ObjectOutputStream
                    (new FileOutputStream(FILE_DATA + text.charAt(2) + ".sav"))) {
                GameInfo gameInfo = new GameInfo(data, x, y, path, count);
                oos.writeObject(gameInfo);
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            jmi.setText(text.substring(0, 3) + "(" + count + "步)");
            //读档信息怎么设置?通过JMenu通过下标获取组件
            loadMenu.getItem(text.charAt(2) - '1').setText(text.substring(0, 3) + "(" + count + "步)");
        } else if (o == loadItem1 || o == loadItem2 || o == loadItem3) {
            //读档和上面的流程一样,读取数据然后initImage就可以咯,需要改一改初始化变量的时候,JItem的显示(有存档但是打开的时候 不显示)
            System.out.println("读档");
            JMenuItem jmi = (JMenuItem) o;
            String text = jmi.getText();
            try (ObjectInputStream ois = new ObjectInputStream
                    (new FileInputStream(FILE_DATA + text.charAt(2) + ".sav"))) {
                GameInfo gameInfo = (GameInfo) ois.readObject();
                data = gameInfo.getData();
                path = gameInfo.getPath();
                x = gameInfo.getX();
                y = gameInfo.getY();
                count = gameInfo.getStep();
                initImage();
            } catch (IOException | ClassNotFoundException ioException) {
                ioException.printStackTrace();
            }
17.完成根据存档初始化JMenu
        //根据存档显示不同的存档与读档数据
        File file = new File(FILE_DATA);
        File[] files = file.listFiles();
        for (File save : files) {
            try (ObjectInputStream ois = new ObjectInputStream
                    (new FileInputStream(save))) {
                GameInfo gameInfo = (GameInfo) ois.readObject();
                int step = gameInfo.getStep();
                saveMenu.getItem(save.getName().charAt(0) - '1').setText("存档" + save.getName().charAt(0) + "(" + step + "步)");
                loadMenu.getItem(save.getName().charAt(0) - '1').setText("存档" + save.getName().charAt(0) + "(" + step + "步)");
            } catch (IOException | ClassNotFoundException ioException) {
                ioException.printStackTrace();
            }
        }
18.完成配置文件功能,可以修改properties中的文件去更换图片
        //公众号
        accountItem.addActionListener(e -> {
            System.out.println("弹出公众号");
            //创建弹框
            JDialog dialog = new JDialog();
            //读取配置文件来建立公众号图片
            Properties properties = new Properties();
            try {
                properties.load(new FileReader(FILE_PROPERTIES));
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            JLabel label = new JLabel(new ImageIcon((String) properties.get("account")));
            label.setBounds(0, 0, 258, 258);
            dialog.getContentPane().add(label);
            dialog.setSize(344, 344);
            dialog.setAlwaysOnTop(true);
            dialog.setLocationRelativeTo(null);
            //弹框不关闭无法设置下面的界面
            dialog.setModal(true);
            dialog.setVisible(true);
        });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值