HHR的小站
享受代码带来的快乐吧
首页

引言

一直以来,Java有一个为人所不满的缺点:啰嗦。有些简单的东西,可能需要撰写更多代码才能完成。
幸好,Java为我们推出了很多新功能,来解决其中的问题。本文主要想介绍Java8的lambda表达式。

lambda

之前的版本

先来看这么一串代码

        String[] name = {"Mike", "Tom", "Jerry", "Potty", "Moggy"};
        Arrays.sort(name, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });

有五个小朋友,他们有不同的名字。我们希望按照字母的顺序为其排序。按照Java7的写法,我们需要完成一个Comparator接口,并实现其中的compare方法。以完成排序。

使用lambda的写法

使用IDEA的朋友们可能发现,之前的代码被标为了黄色。IDEA会将你的代码改成这样

Arrays.sort(name, (o1, o2) -> o1.compareTo(o2));

原本的compare函数消失了,变成了 (o1, o2) -> o1.compareTo(o2)。这是怎么回事呢?

什么是lambda

其实这就是lambda表达式,Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。
(o1, o2) -> o1.compareTo(o2)意为,传入了o1,o2两个参数,将 o1.compareTo(o2) 的值作为返回值。简单的语法就完成了原本五六行代码的工作量。

还能更简单吗?

能!如果使用Java8的另外一个特性,方法引用,撰写的代码量会更少。有关方法引用的使用,我会在之后的文章里进行介绍。

lambda的更多示例

启动子线程

new Thread(() -> System.out.println("Hello World")).start();

等价于

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello World");
            }
        }).start();

显而易见,使用lambda语句,可以使代码更为简洁。

使用滑动窗口算法解决一些问题

在Leetcode上做到了一道题

题目

给你两个长度相同的字符串,st

s 中的第 i 个字符变到 t 中的第 i 个字符需要 |s[i] - t[i]| 的开销(开销可能为 0),也就是两个字符的 ASCII 码值的差的绝对值。

用于变更字符串的最大预算是 maxCost。在转化字符串时,总开销应当小于等于该预算,这也意味着字符串的转化可能是不完全的。

如果你可以将 s 的子字符串转化为它在 t 中对应的子字符串,则返回可以转化的最大长度。

如果 s 中没有子字符串可以转化成 t 中对应的子字符串,则返回 0。

解答

删去其中繁杂的题干,题意大概是从一个自然数串中,找出最长的和小于 maxCost 的串。此题可以用滑动窗口的思路解决。

滑动窗口

定义一个左指针 leftPtr,一个右指针 rightPtr ,开始时将两个指针都置于最左边。右侧指针每次向右移动一格,判断左指针所处的位置是否符合题意。如果不符合,将其向右移动,直到符合题意为止。存储最大的符合题意的距离,即为答案。

简单说来,可以理解成右指针拉着左指针向右动,它们之间用一根线(maxCost)相连。如果线足够长(rightPtr - leftPtr <= maxCost),左指针就不会动,否则它也会跟着向右移。

代码

class Solution {
    public int equalSubstring(String s, String t, int maxCost) {
        int length = s.length();
        int[] cost = new int[length];
        for (int i = 0; i < length; i++) {
            cost[i] = Math.abs(s.charAt(i) - t.charAt(i));
        }
        int rightPtr = 0, leftPtr = 0, max = 0, nowCost = 0;
        while (rightPtr < length) {
            nowCost += cost[rightPtr];
            while (nowCost > maxCost) {
                nowCost -= cost[leftPtr];
                leftPtr++;
            }
            if (rightPtr - leftPtr + 1 > max) {
                max = rightPtr - leftPtr + 1;
            }
            rightPtr++;
        }
        return max;
    }
}

我做了什么?

一个基于Flask的Web应用,输入教务系统的账号密码,即可查询学生的平时成绩

怎么用?

打开这个链接,输入账号密码,即可查看到成绩

想看源代码?

本应用在GitHub上开源,点击这个链接查看

部分代码实现

import json

from flask import Flask, request, render_template

from service import get_score_detail, get_gpa_info, beautify_msg

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/score', methods=["POST"])
def get_score():
    username = request.form['username']
    password = request.form['password']
    year = request.form['year']
    term = request.form['term']
    config = [username, password, year, term]
    score_list = beautify_msg(get_gpa_info(config, get_score_detail(config)))
    return json.dumps(score_list)


if __name__ == '__main__':
    app.run()

指定路由

使用@app.route()方法,可以包含参数指定路由及支持的请求方法

@app.route('/score', methods=["POST"])

获取表单数据

使用 Flask框架提供的 request对象,通过request.form获取表单中的数据

    username = request.form['username']
    password = request.form['password']
    year = request.form['year']
    term = request.form['term']

返回数据

使用 json.dumps方法将需要返回的对象转化为json,返回给前端

    return json.dumps(score_list)

模板页面

将页面放入 template文件夹,在方法中使用render_template函数渲染页面

@app.route('/')
def index():
    return render_template('index.html')

静态资源

将静态资源放入 static 文件夹,即可使用类似于 https://www.example.com/static/css/example.css 的方法访问静态资源

JetBrain全家桶,这是多少开发者梦寐以求的东西。可是,299美元一年的价格,让很多同学望而却步。殊不知,你的学校邮箱,可以让你获得免费的正版全家桶。带上邮箱,来吧!

你需要准备的东西:

  1. 一个.edu的教育邮箱
  2. 不错的网络连接

首先,我们当然要先拥有一个教育邮箱。以浙江工业大学的邮箱为例,打开邮箱(mail.zjut.edu.cn),用户名是你的学号,密码是身份证号的后八位。

进入之后,先改个密码吧

接下来,打开JetBrain的网站( https://www.jetbrains.com/shop/eform/students )填写你的个人信息。注意,填写邮箱时,选择刚才的学校邮箱。

你肯定希望在收件箱看见你的邮件吧。但是由于神奇的原因,这封邮件会出现在你的拦截队列。

进入拦截队列,选择投递邮件,你就可以在收件箱看见它。

点击 Confirm Request

阅读协议,选择 I Accept,你的学生权限申请就通过了。接下来,在新出现的界面注册一个jetbrain账号。

输入信息,点击提交。你就拥有了一套全家桶。

下载你想要的那个吧!

用Java的方式打开数据库课程设计

准备工作

  • JetBrains Intellij IDEA Ultimate
  • JDK 1.8或11

新建项目

打开IDEA我们可以看见下面的起始页面
点击 Create New Page 新建项目,进入 Java 点击下一步,勾选Create project from template,点击下一步设置项目名称、路径、包名等即可创建完成
img
img
img
img

添加依赖

前往mvnrepository.com下载适用于mssql的jdbc驱动用以连接数据库,将连接驱动放入lib文件夹下,右键项目选择Project Structure,进入Libraries,点击+按钮,添加Java Lib,选择lib文件夹点击确定即可
img
img
img
img

初始数据

img

插入数据

//插入数据
//PreparedStatement预编译SQL语句确保安全
//?是占位符,用setString/setInt等方法插入对应占位符的值
try (PreparedStatement ps = conn.prepareStatement("insert into t_01 (name, info) values (?, ?)")) {
    ps.setString(1, "stu10");
    ps.setString(2, "135790");
    ps.execute();
} catch (SQLException e) {
    e.printStackTrace();
}

插入结果

img

更新数据

//更新数据,将id=10的记录的info字段改为hello world
try (PreparedStatement ps = conn.prepareStatement("update t_01 set info=? where id=?")) {
    ps.setString(1, "hello world");
    ps.setInt(2, 10);
    ps.execute();
} catch (SQLException e) {
    e.printStackTrace();
}

更新结果

img

删除数据

//删除数据,删除id=10的记录
try (PreparedStatement ps = conn.prepareStatement("delete from t_01 where id=?")) {
    ps.setInt(1, 10);
    ps.execute();
} catch (SQLException e) {
    e.printStackTrace();
}

删除结果

img

查询数据

//查询所有数据并输出
try (PreparedStatement ps = conn.prepareStatement("select * from t_01")) {
    try (ResultSet rs = ps.executeQuery()) {
        while (rs.next()) {
            int id = rs.getInt("id");
            String name = rs.getString("name");
            String info = rs.getString("info");
            System.out.println("id=" + id + ", name=" + name + ", info=" + info);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
} catch (SQLException e) {
    e.printStackTrace();
}

查询结果

img