Java学习笔记2——常用类

目录

  • 1 内部类
    • 1.1 成员内部类
    • 1.2 静态内部类
    • 1.3 局部内部类
    • 1.4 匿名内部类
  • 2 Object类
    • 2.1 getClass()方法
    • 2.2 hashCode()方法
    • 2.3 toSring()方法
    • 2.4 equals()方法
    • 2.5 finalize()方法
  • 3 包装类
    • 3.1 类型转换与装箱、拆箱
    • 3.2 整数缓冲区
  • 4 String类
    • 4.1 常用方法
    • 4.2 可变字符串
  • 5 BigDecimal类
  • 6 时间类型
    • 6.1 Date类
    • 6.2 Calendar类
    • 6.3 SimpleDateFormat类
    • 6.4 System类

1 内部类

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类

内部类特点:
1.编译之后会生成独立的字节码文件
2.内部类可直接访问外部类的私有成员,而不破坏封装
3.内部类可以为外部类提供必要的内部功能组件

1.1 成员内部类

在类的内部定义,与实例变量、实例方法同级别的类。

创建内部类对象时,必须依赖外部类对象。
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
或者一步到位:Outer.Inner inner = new Outer().new Inner();

当外部类、内部类存在同名属性时,会优先访问内部类属性。如果需要调用外部类属性,需要使用Outer.this.属性

成员内部类不能定义静态成员,但是可以定义静态常量。

1.2 静态内部类

不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。(相当于外部类)

直接创建静态内部类对象:
Outer.Inner Inner = new Outer.Inner();注意new Outer后面没有括号,即没有创建对象,表明Outer和Inner只是包含关系。

只有静态内部类才能被static修饰,普通类不能被static修饰。

静态内部类调用外部类对象的属性需要使用Outer.属性。
静态内部类自己的的属性和方法直接调用。

1.3 局部内部类

定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。
不能加任何访问修饰符。

如果需要在其他普通类调用局部内部类里面的方法(方法2),要在外部类的包含了局部内部类的局部方法(方法1)中创建局部内部类对象:

class Outer{方法1(){class Inner{方法2(){}}Inner inner = new Inner();inner.方法2();	}	
}
class OtherClass{Outer outer = new Outer();outer.方法1();//这样就可以调用到方法2了
}

局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。
访问局部变量 jdk1.7要求局部方法中的变量必须为常量final、jdk1.8自动添加final修饰(只是不显示而已)

1.4 匿名内部类

没有类名的局部内部类(一切特征都与局部内部类相同)。

必须继承一个父类或者实现一个接口。

定义类、实现类、创建对象的语法合并,只能创建一个该类的对象。

优点:减少代码量;缺点:可读性较差。

// 使用匿名内部类优化(相当于创建了一个局部内部类)
Usb usb = new Usb(){ // Usb为一个接口/抽象类/父类(多态)@Overridepublic void service(){sout("连接电脑成功,fan开始工作")}
};
usb.service();

2 Object类

  • 超类、基类,所有类的直接或间接父类,位于继承树的最顶层
  • 任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承
  • Object类中所定义的方法,是所有对象都具备的方法
  • Object类型可以存储任何对象
    作为参数,可接受任何对象
    作为返回值,可返回任何对象

2.1 getClass()方法

public final Class<?> getClass(){}

返回引用中存储的实际对象类型。
应用:通常用于判断两个引用中实际存储对象类型是否一致。

Class class1 = s1.getClass();
Class class2 = s2.getClass();
// getClass返回 class类型
if(class1==class2){
// 判断s1 和 s2是不是同一个类型
}

2.2 hashCode()方法

public int hashCode(){}

返回该对象的哈希码值。

哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的值。

一般情况下相同对象返回相同哈希码。

2.3 toSring()方法

public String toSring(){}

返回该对象的字符串表示(表现形式)
可以根据程序需求覆盖该方法,如:展示对象各个属性值

2.4 equals()方法

public boolean equals(Object obj){}

默认实现为(this == obj), 比较两个对象地址是否相同。

可进行覆盖,比较两个对象的内容是否相同。

// 判断两个对象是否相等
Student s4 = new Strudent("小明", 17);
Student s5 = new Strudent("小明", 17);
sout(s4.equals(s5)); // false 堆中地址不同// 重写 改变其比较内容
/*
步骤  1. 比较两个应用是否指向同一个对象2. 判断obj是否为null3. 判断两个引用只想的实际对象类型是否一致4. 强制类型转换5. 依次比较各个属性值是否相同
*/
@override
public boolean equals(Object obj){// 1.判断两个对象是否是同一个引用if(this == obj){return true;}// 2.判断obj是否为nullif(obj == null){return false;}// 3.判断是否是同一个类型// if(this.getClass() == obj.getClass()){//// }//最好使用instanceof 判断对象是否是某种类型if(obj instanceof Student){// 4.强制类型转换Student s = (Student)obj;// 5. 比较属性if(this.name.equals(s.getName()) && this.age == s.getAge()){return true;}}return false;
}

2.5 finalize()方法

当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。

垃圾对象:没有有效引用指向此对象时,为垃圾对象。

垃圾回收:由GC销毁垃圾对象,释放数据存储空间。

自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。

手动回收机制:使用System.gc();通知JVM执行垃圾回收。

3 包装类

  • 基本数据类型所对应的引用数据类型。
  • Object 可统一所有数据,包装类的默认值是null。
基本数据类型包装类型
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean
charCharacter

3.1 类型转换与装箱、拆箱

8种包装类提供不用类型间的转换方式:

  1. Number父类中提供的6个共性方法
  2. parseXXX( )静态方法
  3. valueOf( )静态方法

注意:需保证类型兼容,否则抛出NumberFormatException异常

//装箱,基本类型转成引用类型
//拆箱,引用类型转成基本类型
// jdk1.5之后提供了自动装箱拆箱int age = 30;//自动装箱。自动完成了:Integer integer = Integer.valueOf(age);Integer integer = age;//// 自动拆箱。自动完成了该行代码:int age2 = integer.intValue();int age2 = integer;

基本类型和字符串之间转换:

 // 1. 基本类型转成字符串int n1 = 100;// 方法1 使用+号String s1 = n1 + "";// 方法2 使用Integer中的toString()方法String s2 = Integer.toString(n1);String s2 = Integer.toString(n1, x); // x为进制要求// 2. 字符串转成基本类型String str = "150";// 使用Integer.parseXXX();int n2 = Integer.parseInt(str);// boolean 字符串形式转成基本类型,"true" ---> true 非“true ———> falseString str2 = "true";boolean b1 = Boolean.parseBoolean(str2);

3.2 整数缓冲区

Java预先在堆内存中创建了256个常用的整数包装类型对象,即[-128,127],当 Integer i =Integer.valueOf(x)处于这个区间之内,就直接将堆内存中的那个值的地址赋给i。如果x相同,i的地址都相同,如果不处于那个区间,则new一个对象。(此为源码解读)
可以参考:低调的洋仔

在实际应用当中,对已创建的对象进行复用(如下面的integer3和integer4例子)

psvm(String[] args){// 面试题Integer integer1 = new Integer(100);Integer integer2 = new Integer(100);sout(integer1 == integer2); // falseInteger integer3 =100;// 自动装箱// 相当于调用 Integer.valueOf(100);Integer integer4 =100;sout(integer3 == integer4); // trueInteger integer5 = 200;// 自动装箱Integer integer6 = 200;sout(integer5 == integer6); // false// 因为缓存区数组 [-128, 127] 在这之内地址一样
}

4 String类

  • 字符串是常量,创建之后不可改变
  • 字符串字面值存储在字符串池中,可以共享
  • String s = “Hello”;产生一个对象,字符串池中存储
  • String s = new String(“Hello”); 产生两个对象,堆、池各一个
    (由以上可知,因为产生了对象。可以直接用“字符串名.方法()”来调用方法)

4.1 常用方法

  • public int length():返回字符串长度

  • public char charAt(int index):根据下标获取字符

  • public boolean contains(String str):判断当前字符串是否包含str

  • public char[] toCharArray():将字符串转换成数组

  • public int indexOf(String str):查找str首次出现的下标,存在则返回该下标;不存在则返回-1。
    public int indexOf(String str, int fromIndex),从fromIndex下标开始查找。

  • public int lastIndexOf(String str):查找字符串在当前字符串中最后一次出现的下标索引

  • public String trim():去掉字符串前后的空格

  • public String toUpperCase():将小写转成大写
    public String toLowerCase():将大写转成小写

  • public boolean endsWith(String str):判断字符串是否以str结尾
    public boolean starsWith(String str):判断字符串是否以str开头

  • public String replace(char oldChar, char newChar):将旧字符串替换成新字符串

  • public String[] split(String str):根据str做拆分,str可以是空格,如split(" “)。str可以是空格或逗号,如split(”[ ,]")。如果要将一个或多个空格或括号作为str,则酱紫写split("[ ,]+")

  • public boolean equals(Object anObject):用于比较两个字符串的内容是否相等

  • public boolean equalsIgnoreCase(String anotherString):用于将字符串与指定的对象比较,不考虑大小写

  • public int compareTo(String
    anotherString):如果字符串的第一个字符和参数字符串的第一个字符不等,结束比较,返回两字符的ASCII码差值。

    如果字符串的第一个字符和参数字符串的第一个字符相等,则以两者的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。
    如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。

	String str1 = "abc";String str2 = "aycccc";String str3 = "abc123";int result = str1.compareTo( str2 );sout(result);//-23result = str2.compareTo( str3 );sout(result);//23result = str3.compareTo( str1 );sout(result);//3

4.2 可变字符串

  • StringBuffer : 可变长字符串,运行效率慢、线程安全
  • StringBuilder : 可变长字符串,运行快、线程不安全

上面两者效率都比String高且节省内存。

psvm(String[] args){// StringBuffer 和 StringBuilder 用法一致StringBuffer sb = new StringBuffer();//StringBuilder sb = new StringBuilder();sb.append("java no1");// 1. append(); 在最后面追加sb.insert(0, "内容xx");  // 2. insert(); 插入内容sb.replace(0, 9, str); // 3.replace(); 替换(区间左闭右开)[0,9)sb.delete(0, 5);  // 4. delete(); 删除(左闭右开)[0,5)sb.delete(0, sb.length());  // 5. 清空
}

5 BigDecimal类

很多实际应用中需要用到精确运算,而double是近似值存储,不符合要求。需要用到BigDecimal。

位置:java.math包中
作用:精确计算浮点数
创建方式:BigDecimal bd = new BigDecimal(“x.xxx…”);(建议选择字符串类型)

  • 加:BigDecimal add(BigDecimal bd)
  • 减:BigDecimal subtract(BigDecimal bd)
  • 乘:BigDecimal multiply(BigDecimal bd)
  • 除法:divide(BigDecimal bd, int scal, RoundingMode mode)
    参数scal:指定精确到小数点后几位
    参数mode:指定小数部分的取舍模式,四舍五入模式为RoundingMode.HALF_UP
    例如:
BigDecimal bd1 = new BigDecimal("1.0"); 
BigDecimal bd2 = new BigDecimal("0.9");
// 减法
BigDecimal r1 = bd1.subtract(bd2);
sout(r1); // 0.1
BigDecimal r = new BigDecimal("14").subtract(new BigDecimal("4")).divide(new BigDecimal("3"), 3,RoundingMode.HALF_UP); 
//sout(r)   3.333
//(14-4)÷3,保留三位小数,使用四舍五入取舍

6 时间类型

6.1 Date类

Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已经被Calendar类中的方法所取代

时间单位:1s = 1,000ms = 1,000,000 μs = 1,000,000,000 = ns

psvm(String[] args){// 1 创建Date对象Date date1 = new Date();sout(date1.toString()); //WED Sept 02 22:25:23 CST 2020sout(date1.toLocaleString()); // 已过时,但也能用  2020-9-2// 创建昨天的Date date2 = new Date(date1.getTime() - (60*60*24*1000));sout(date2.toLocaleString());// 2 方法after beforeboolean b1 = date.after(date2);sout(b1); //trueboolean b2 = date1.before(date2);sout(b2); //false// 比较compareTo();int d = date1.compareTo(date2);sout(d); // 比较两个日期的顺序。date1比date2大则为正,否则负// 比较是否相等 equals()boolean b3 = date1.equals(date2);sout(b3); // false
}

6.2 Calendar类

  • Calendar提供了获取或设置各种日历字段的方法
  • 构造方法 protected Calendar(); 由于是protected 所以无法直接创建

其他方法:

方法名说明
static Calendar getInstance()使用默认时区和区域获取日历
void set(int year, int month, int date, int hourofday, int minute, int second)设置日历的年、月、日、时、分、秒
int get(int field)返回给定日历字段的值。字段比如年、月、日
void setTime(Date date)用给定的date设置此日历时间
Date getTime()返回一个date表示此日历的时间
void add(int field, int amount)按照日历的规则,给指定字段添加或减少时间量
long getTimeInMilles()毫秒为单位返回该日历的时间值

例子:

psvm(String[] args){// 1. 创建 Calendar 对象Calendar calendar = Calendar.getInstance();sout(calendar.getTime().toLocaleString());// 2. 获取时间信息// 获取年int year = calendar.get(Calendar.YEAR);// 获取月 从 0 - 11int month = calendar.get(Calendar.MONTH);// 日int month = calendar.get(Calendar.DAY_OF_MONTH);// 小时int hour = calendar.get(Calendar.HOUR_OF_DAY);// 分钟int minute = calendar.get(Calendar.MINUTE);// 秒int second = calendar.get(Calendar.SECOND);// 3. 修改时间Calendar calendar2 = Calendar.getInstance();calendar2.set(Calendar.DAY_OF_MONTH, x);// 4. add修改时间calendar2.add(Calendar.HOUR, x); // x为正就加 负就减// 5. 补充方法int max = calendar2.getActualMaximum(Calendar.DAY_OF_MONTH);// 月数最大天数int min = calendar2.getActualMinimum(Calendar.DAY_OF_MONTH);
}

6.3 SimpleDateFormat类

  • SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类

常用的时间模式字母:

字母日期或时间示例
y2019
M年中月份08
d月中天数10
H一天中小时(0-23)22
m分钟16
s59
S毫秒356
psvm(String[] args) throws ParseException{// 1. 创建对象SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");// 2. 创建DateDate date = new Date();// 格式化date(日期转成字符串)String str = sdf.format(date);sout(str);// 解析(字符串转成时间)Date date2 = sdf.parse("1948/03/12");//必须要与SimpleDateFormat()定义的格式一致sout(date2); 
}

6.4 System类

主要用于获取系统的属性数据和其他操作,构造方法私有的

方法名说明
static void arraycopy(…)复制数组
static long currentTimeMillis();获取当前系统时间,返回毫秒值
static void gc();建议jvm赶快启动垃圾回收期器回收垃圾
static void exit(int status);退出jvm 如果参数是0表示正常退出jvm 非0表示异常退出
//arraycopy 数组复制//src 源数组 //srcPos 从哪个位置开始复制0 //dest 目标数组 //destPos 目标数组的粘贴的开始位置 //length 复制的长度int[] arr = {20, 18, 39, 3};int[] dest = new int [4];System.arraycopy(arr, 0, dest, 1, 2);for (int s:dest) {System.out.println(s);// 输出:0 20 18 0}
}

Arrays.copyOf(original, newLength)也可以复制数组,但这个的源码其实还是用了System类的arraycopy方法

currentTimeMillis()方法的一个应用:获取程序运行用时

	long start = System.currentTimeMillis();//{程序}long end = System.currentTimeMillis();sout("用时:"+(end-start));
	System.exit(0);//下面的代码不再执行,因为JVM已经退出

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

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

相关文章

Mysql密码忘记了怎么办?

停止mysql&#xff1a; sudo /etc/init.d/MySQL stop(可能有其它的方法&#xff0c;总之停止MySQLd的运行就可以了) 修改mysql的配置文件&#xff1a; 在/etc/mysql/mysql.conf.d/mysqld.cnf文件中添加skip-grant-tables&#xff0c;每台电脑的文件位置可能不同。 重新启动mysq…

html:(31):层叠和重要性

层叠 我们来思考一个问题&#xff1a;如果在html文件中对于同一个元素可以有多个css样式存在并且这多个css样式具有相同权重值怎么办&#xff1f;好&#xff0c;这一小节中的层叠帮你解决这个问题。 层叠就是在html文件中对于同一个元素可以有多个css样式存在&#xff0c;当有…

架构设计分布式数据结构与算法面试题

目录架构设计请列举出在JDK中几个常用的设计模式&#xff1f;什么是设计模式&#xff1f;你是否在你的代码里面使用过任何设计模式&#xff1f;静态代理、JDK动态代理以及CGLIB动态代理静态代理动态代理cglib代理单例模式工厂模式观察者模式装饰器模式秒杀系统设计分布式分布式…

Java学习笔记3——集合框架

文章目录1 集合的概念2 Collection体系集合Collection父接口3 List接口与实现类List接口List实现类ArrayListVectorLinkedList4 Set接口与实现类Set接口Set实现类HashSetTreeSet5 Map接口与实现类Map接口Map接口的内部接口Entry1 集合的概念 概念&#xff1a;对象的容器&#…

CLOSE_WAIT状态的原因与解决方法

这个问题之前没有怎么留意过&#xff0c;是最近在面试过程中遇到的一个问题&#xff0c;面了两家公司&#xff0c;两家公司竟然都面到到了这个问题&#xff0c;不得不使我开始关注这个问题。说起CLOSE_WAIT状态&#xff0c;如果不知道的话&#xff0c;还是先瞧一下TCP的状态转移…

html:(32):字体,字号,颜色

文字排版--字体 我们可以使用css样式为网页中的文字设置字体、字号、颜色等样式属性。下面我们来看一个例子&#xff0c;下面代码实现&#xff1a;为网页中的文字设置字体为宋体。 body{font-family:"宋体";} 这里注意不要设置不常用的字体&#xff0c;因为如果用…

POJ-1845 数论

题意就是输入 a,b 输出 a的b次方的因子求和并对9902 取模 这题可以对因子化简 由于唯一分解定理 可以把a表示成 p1^q1*p2^q2...*pn^qn 也就是说 a^b p1^(q1*b)*p2^(q2*b)...*pn^(qn*b) 由于约数和公式可得a^b得约数求和为(1p1p1^2p1^3...p1^(q1*b))(1p2p2^2p2^3...p2^(q2*b…

html:(33):文字排版粗体和斜体

文字排版--粗体 我们还可以使用css样式来改变文字的样式&#xff1a;粗体、斜体、下划线、删除线&#xff0c;可以使用下面代码实现设置文字以粗体样式显示出来。 p span{font-weight:bold;} 在这里大家可以看到&#xff0c;如果想为文字设置粗体是有单独的css样式来实现的&…

[剑指offer][JAVA]面试题第[14-1、2]题[剪绳子][Leetcode][第343题][整数拆分][数学][动态规划][背包]

【问题描述】[中等] 给你一根长度为 n 的绳子&#xff0c;请把绳子剪成整数长度的 m 段&#xff08;m、n都是整数&#xff0c;n>1并且m>1&#xff09;&#xff0c;每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少&#xff1f;…

Java学习笔记4——I/O框架

目录1 流的概念2 流的分类3 字节流文件字节流FileInputStreamFileOutputStream字节缓冲流BufferedInputStreamBufferedOutputStream对象流ObjectOutputStreamObjectInputStream注意事项5 字符流文件字符流FileReaderFileWriter字符缓冲流BufferedReaderBufferedWriter转换流Inp…

snappy

参考From <https://dirtysalt.github.io/snappy.html> Snappy API From <https://www.npmjs.com/package/snappy> Snappy 是一个 C 的用来压缩和解压缩的开发包&#xff0c;其目标不是较大限度压缩&#xff0c;而且不兼容其他压缩格式。Snappy 旨在提供高速压缩速…

2017百度之星资格赛 1003 度度熊与邪恶大魔王

本题我们可以类比背包 背包dp[i][j] 表示再有i个物品下j个空间所获得的最大价值 本题dp[i][j] 可以表示干掉i个血量j个防御力下的最小花费 我们看其实我们就是在不同血量之间转移 如果当前技能的攻击力 > 当前防御力 如果攻击力能干掉怪物那么dp[i][j] min(花费,dp[…

html:(34):下划线和删除线

文字排版--下划线 有些情况下想为文字设置为下划线样式&#xff0c;这样可以在视觉上强调文字&#xff0c;可以使用下面代码来实现&#xff1a; p a{text-decoration:underline;}<p>三年级时&#xff0c;我还是一个<a>胆小如鼠</a>的小女孩。</p> &…

设计模式--职责链模式

实验15&#xff1a;职责链模式 本次实验属于模仿型实验&#xff0c;通过本次实验学生将掌握以下内容&#xff1a; 1、理解职责链模式的动机&#xff0c;掌握该模式的结构&#xff1b; 2、能够利用职责链模式解决实际问题。 [实验任务]&#xff1a;财务审批 某物资管理系统…

uoj#188. 【UR #13】Sanrd(Min_25筛)

题面 传送门 题解 这是一道语文题 不难看出&#xff0c;题目所求即为\(l\)到\(r\)中每个数的次大质因子 我们考虑\(Min\_25\)筛的过程&#xff0c;设 \[S(n,j)\sum_{i1}^nsec_p(i)[min_p(i)\geq P_j]\] 用人话来说的话&#xff0c;就是\(S(n,j)\)表示\(1\)到\(n\)之间所有满足最…

[剑指offer]面试题第[66]题[构建乘积数组][Leetcode][JAVA][第238题][除自身以外数组的乘积][数组]

【问题描述】[中等] 给你一个长度为 n 的整数数组 nums&#xff0c;其中 n > 1&#xff0c;返回输出数组 output &#xff0c;其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。示例:输入: [1,2,3,4] 输出: [24,12,8,6]提示&#xff1a;题目数据保证数组之中任…

【发现问题】Java中PrintWriter和BufferedWriter的区别

BufferedWriter: 将文本写入字符输出流&#xff0c;缓冲各个字符从而提供单个字符&#xff0c;数组和字符串的高效写入。通过write()方法可以将获取到的字符输出&#xff0c;然后通过newLine()进行换行操作。BufferedWriter中的字符流必须通过调用flush方法才能将其刷出去。并…

玩转oracle 11g(47):oracle删除非空表空间

DROP TABLESPACE WIICARE INCLUDING CONTENTS AND DATAFILES; --wiicare表空间名

【发现问题】Java中PrintStream和PrintWriter的区别

PrintStream和PrintWriter的API几乎相同&#xff0c;都能输出各种形式的数据&#xff0c;构造方法也几乎相同。两者有何区别&#xff1f; **2个类的功能基本相同&#xff0c;PrintStream能做的PrintWriter也都能实现&#xff0c;并且PrintWriter的功能更为强大。**但是由于Pri…

centos 6.5 安装redis

1. 下载redis&#xff0c;编译安装 下载地址&#xff1a;https://redis.io/download&#xff08;建议大家都选择稳定版本&#xff09; 下载到本地&#xff0c;然后上传到集群 当然也可以通过命令行直接在线下载 $ wget http://download.redis.io/releases/redis-5.0.3.tar.gz $…