java基础开发实战重点总结


java基础重点总结:


String类:

String类是用于描述字符串事物的。它提供了多个方法对字符串进行操作。
常见的操作。
1,获取
1.1字符串中包含的字符数,也就是字符串的长度。
int length();
1.2根据位置获取位置上的某个字符。
char charAt(int index);

1.3 String类的indexOf方法,lastIndexOf方法,可以传入int和String参数。各4个方法:

1.3 .1根据字符获得该字符在字符串中的位置。
int indexOf(int ch);返回ch字符在字符串中第一次出现的位置。
int indexOf(int ch,int fromIndex);从fromIndex开始,获取ch字符在该字符串中出现的位置。
int indexOf(String str);返回str字符串在该字符串中第一次出现的位置。
int indexOf(String str,int fromIndex);从fromIndex指定位置开始,返回str字符串在字符串中出现的位置。

1.3 .2反向开始搜索ch字符串出现的位置。
int lastIndexOf(int ch);但字符串角码不会变的。

2,判断
2.1字符串中是否包含某一个子串。
boolean contains(str);
特殊之处:indexOf(str):可以索引str第一次出现位置,如果返回-1.表示该str不在字符串中存在。所以,也可以用于对指定判断是否包含。
if(str.indexOf("aa")!=-1)
而且该方法即可以判断,又可以获取出现的位置。
2.2字符中是否有内容。
boolean isEmpty();原理就是判断长度是否为0。为0返回true。
2.3字符串是否是以指定内容开头。
boolean startsWith(str);

boolean startsWith(String prefix)测试此字符串是否以指定的前缀开始。

boolean startsWith(String prefix, int toffset)测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
2.4字符串是否是以指定内容结尾。
boolean endsWith(str);
2.5获取字符串内容是否相同.复写了Object类中的equals方法.
boolean equals(str);
2.6判断内容是否相同,并忽略大小写.
boolean equalsIgnoreCase();

3,转换
3.1将字符数组转成字符串.
构造函数:String(char[])
          String(char[],offset,count):将字符数组中的一部分转成字符串。
静态方法:
static String copyValueOf(char[]);
static String copyValueOf(char[] data, int offset, int count);
3.2 将字符串转成字符数组。
char[] toCharArray();
3.3 将字节数组转成字符串。
String(byte[])
String(byte[],offset,count):将字节数组中的一部分转成字符串。
3.4 将字符串转成字节数组。
byte[] getBytes():
3.5 将基本数据类型转成字符串。
static String valueOf(int)
static String valueOf(double)
如:3+"";与String.valueOf(3);效果相同

copyValueOf()共2个方法与valueOf()一样

String类的valueOf方法是静态方法,可以传入boolean 等不同参数、

表示:返回 boolean 等参数的字符串。

传入参数:boolean,char,char[],(char[] data, int offset, int count),double,float,int,long,Object 共9个方法

如:

static String    valueOf(boolean b)
                   返回 boolean 参数的字符串表示形式。

特殊:字符串和字节数组在转换过程中,是可以指定编码表的。
4,替换
String replace(oldchar,newchar);

String replace(char oldChar, char newChar)

返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。

String replace(CharSequence target, CharSequence replacement)

使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。

String replaceAll(String regex, String replacement)

使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

String replaceFirst(String regex, String replacement)

用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
5,切割 返回的是字符串类型的数组.
String[] split(regex);

String[] split(String regex)根据给定正则表达式的匹配拆分此字符串。

String[] split(String regex, int limit)根据匹配给定的正则表达式来拆分此字符串。
6,子串。获取字符串中的一部分。传入角标.
String substring(begin);
String substring(begin,end);从头不包括尾(0,str.length())

CharSequence   subSequence(int beginIndex, int endIndex)返回一个新的字符序列,它是此序列的一个子序列。
7,转换,去除空格,比较。
7.1 将字符串转成大写或者小写。
String toUpperCase();
String toLowerCase();

String toLowerCase(Locale locale)使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。

String toUpperCase(Locale locale)使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。

7.2 将字符串两端的多个空格去除。
String trim();
7.3 对两个字符串进行自然顺序的比较。
int compareTo(string);

int compareToIgnoreCase(String str)
按字典顺序比较两个字符串,不考虑大小写。

int

codePointAt(int index)
返回指定索引处的字符(Unicode 代码点)。

int

codePointBefore(int index)
返回指定索引之前的字符(Unicode 代码点)。

int

codePointCount(int beginIndex, int endIndex)
返回此 String 的指定文本范围中的 Unicode 代码点数。

String

concat(String str)
将指定字符串连接到此字符串的结尾。

boolean

contentEquals(CharSequence cs)
将此字符串与指定的 CharSequence 比较。

boolean

contentEquals(StringBuffer sb)
将此字符串与指定的 StringBuffer 比较。

static String

format(Locale l, String format, Object... args)
使用指定的语言环境、格式字符串和参数返回一个格式化字符串。

static String

format(String format, Object... args)
使用指定的格式字符串和参数返回一个格式化字符串。

byte[]

getBytes(Charset charset)
使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。

void

getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)
已过时。该方法无法将字符正确转换为字节。从 JDK 1.1 起,完成该转换的首选方法是通过 getBytes() 方法,该方法使用平台的默认字符集。

byte[]

getBytes(String charsetName)
使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

void

getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将字符从此字符串复制到目标字符数组。

int

hashCode()
返回此字符串的哈希码。

String

intern()
返回字符串对象的规范化表示形式。

boolean

matches(String regex)
告知此字符串是否匹配给定的正则表达式

int

offsetByCodePoints(int index, int codePointOffset)
返回此 String 中从给定的 index 处偏移 codePointOffset 个代码点的索引。

boolean

regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
测试两个字符串区域是否相等。

boolean

regionMatches(int toffset, String other, int ooffset, int len)
测试两个字符串区域是否相等。

String

toString()
返回此对象本身(它已经是一个字符串!)。

内部类:

1内部类(概况):


成员内部类:类的成员之一
  嵌套类:静态成员内部类
  
局部内部类:(不常用)把一个类定义在局部。局部:方法内部(构造器内部)
  局部匿名内部类:(常用)定义在赋值语句中,方法调用语句中,return语句中。
  
2局部匿名内部类:没有名字的内部类。它是内部类的简化写法。
A:前提:内部类可以继承或实现一个外部类或者接口。
B:格式为:new 类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}
C:简单理解:就是建立一个带内容的外部类或者接口的子类匿名对象。
局部匿名内部类代码举例(掌握)


//匿名类是定义在赋值语句中。


import java.util.Comparator;


public class Test {
public static void main(String[] args) {


       Comparator c = new Comparator(){
public int compare(Object o1, Object o2) {
return 0;
}
};
     fun(c);
}
public static void fun(Comparator c) {
}


}


//匿名类是定义在方法调用语句中。


public class Test {
public static void main(String[] args) {


        
     Fun(new Comparator(){
public int compare(Object o1, Object o2) {
return 0;
}
};


public static void fun(Comparator c) {
}


}


//匿名类是定义在return语句中。(见方式二)


import java.util.Comparator;


public class Test {
public static void main(String[] args) {


}
public static void fun(Comparator c) {
      /*  方式一
Comparator c = new Comparator(){
public int compare(Object o1, Object o2) {
return 0;
}
};
     
        Return c;
*/
//方式二
          return new Comparator(){
public int compare(Object o1, Object o2) {
return 0;
}


}

集合:

集合:存储对象的容器。
特点:长度可变,任意类型的对象。



集合下有两大体系Collection体系,Map体系
Collection:add,remove,contains,size,iterator
|--List:元素有序(存入顺序和取出顺序),可重复。
get,listIterator(List的常用特殊方法 )
|--ArrayList
底层数据结构是数组,查询快,增删慢。(注:什么是数据结构:数据结构是组织数据的方式,每个集合的存数据取数据都要掌握)
线程不安全,效率高。
|--LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
|--Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
|--Set:元素无序,不可重复。
|--HashSet
底层数据结构是哈希表。
如何保证元素的唯一性呢?
它依赖hashCode方法和equals方法。
|--LinkedHashSet
|--TreeSet
底层数据结构是二叉树。
如何保证元素的唯一性呢?
两种方式:
对象具备比较性:Comparable   (含有compareTo(T o) 实现)构造方法TreeSet()
集合具备比较性:Comparator    (含有这个构造器)      构造方法TreeSet(Comparator<? super E> comparator)  接口 Comparator<T>的方法int compare(T o1,T o2)
谁的优先级高:
如果集合有比较器,那么就使用集合比较器来比较元素;
如果集合没有比较器,那么使用对象的自然顺序;
如果对象没有备自然顺序,那么就出异常。   
Map:键值对方式存储数据。键不可以重复,值可以重复。
put,get,size,keySet,entrySet,values,remove
|--HashMap
|--TreeMap

练习:
用ArrayList存储自定义对象(Person:name,age)。并加泛型。
存3个Person,并遍历。


思路:
集合就是为了存储数据。遍历数据。


步骤:
创建集合对象
创建元素对象
把元素对象添加到集合对象中
遍历集合
通过迭代器
通过集合对象获取到迭代器对象
调用迭代器的hasNext方法判断是否还有元素
调用迭代器的next方法取出元素


集合使用总结:


是键值对形式的吗?
|--是:Map
|--需要排序吗:
|--需要:TreeMap
|--不需要:HashMap


如果不知道使用哪个Map,就是用HashMap。


|--不是:Collection
|--保证元素唯一吗?
|--保证 Set
|--需要排序吗:
|--需要:TreeSet
|--不需要:HashSet


如果不知道使用哪个Set,就是用HashSet。
|--不保证 List
|--需要考虑线程问题吗?
需要:Vector(一般也不用。用Collections下面的方法)
不需要:
|--主要用于查询 用ArrayList
|--主要用于增删 用LinkedList




如果不知道使用哪个List,就使用ArrayList。


(理解)注:ArrayList,LinkedList都可以编写栈和队列,但用LinkedList,增删快
   栈(后进先出,相当于:大缸)队列(先进先出!相当于:没底的管道!)
   Set底层用的是Map  如:set.add("a"); 底层实际上是 map.put("a", new Object()); 这里new Object()没有实际意义
二叉树(理解)
  1特点:二叉树中每个节点都比自己左边节点的值大,比右边节点的值小。


    2添加元素
添加进来的第一个元素就是根节点;
然后再添加第二个元素时,与根节点进行比较。
大于根节点,新元素放到根节点的右节点位置;
小于根节点,放到根节点的左节点位置;
等于根节点,那么添加失败。
    3 遍历二叉树
   遍历二叉树是原则是先左,然后当前节点,最后是右。
如:
排序前:8,4,2,6
经过二叉树排列后
排序后:2, 4,6,8
从小到大排列,升序排列


接口 Comparable<T>只有一个方法
int compareTo(T o) 
          比较当前对象与参数对象的顺序。 


字符串String类 实现了Comparable接口
任何有compareTo方法的类称为有自然顺序(字典顺序)
String类有compareTo方法说明String类有自然顺序,有自然顺序可以排序 如:"a".compareTo("b") 返回-1 说明字符串b大






每个集合的存数据取数据都要掌握!
存取的(遍历)方式:Map 两种
   set 两种
            List常用三种,一共五种(接口List 还有listIterator(),Object[] toArray()  把toArray()转变Object[]数组再循环遍历(day17) )
Map 两种:遍历:
 * 方式1:
 * 通过获取所有丈夫的集合。keySet
 * 遍历Set集合,获取到每一个丈夫。迭代器
 * 通过丈夫找妻子。get
 * 
 * 方式2:
 * 获取的是结婚证的集合。entrySet
 * 遍历Set集合,获取到每一个结婚证。迭代器
 * 对着结婚证念名字。getKey,getValue
 set 两种:遍历方式:
 * 1:迭代器
 * 2:增强for (java1.5特性用来取代迭代器的)
 * 3: toArray(T[] a) (不常用)              (来自接口 Collection<E>的方法)
List常用三种,一共五种: List体系取出数据的方式:
 * 1:迭代器 /day17_01_iterator.cn.itcast.ArrayListTest
 * 2:普通for循环 /day17_01_iterator.cn.itcast.ArrayListTest
 * 3:增强for循环 /day17_01_iterator.cn.itcast.ArrayListTest
 * 4: toArray(T[] a) (不常用)             (来自接口 Collection<E>的方法)/day17_02_fanxing/src/cn/itcast/Demo2.java
 * 5: listIterator(int index)(十分不常用)  (来自接口 List<E>的方法)/day17_01_iterator.cn.itcast.ArrayListTest

IO :

day22
1按照操作数据分
字节流
字符流
2API的使用
3File类
File类的练习(掌握)
A:获取指定目录(当前目录)下的指定后缀结尾的文件。
**不使用文件名称过滤器
**使用文件名称过滤器
/*成员方法或者构造方法,传递的参数是接口的时候,
*这个地方传递肯定是实现了这个接口的子类对象。
*有两种方式:
*1:自定义类实现接口
*2:匿名内部类实现 
*当接口中方法少于3个的时候,建议使用匿名内部类。)
*/
File file = new File("d:\\");


String[] strArray = file.list(new FilenameFilter(){
public boolean accept(File dir,String name)
{
return new File(dir,name).isFile() && name.endsWith(".java");
}
});


for(String s : strArray)
{
System.out.println(s);
}
B:递归指定目录下所有的以.java结尾的文件
C:删除带内容的目录(递归删除)
4递归的案例(掌握)
A:递归求阶乘
B:求斐波纳契数列的第二十项
day23


1:IO流的操作(掌握)
(1)字符输出流的使用。(掌握)
步骤:
创建字符输出流对象
调用字符输出流对象的write方法
write(int ch)
write(int[] chs)
write(int[] chs,int index,int len)
write(String str)
释放资源


代码体现:
FileWriter fw = new FileWriter("fw.txt");


fw.write("hello,io");
fw.flush();


fw.close();


问题?
创建字符输出流对象做了几件事情?
1:调用操作系统的资源创建了一个文本文件
2:创建了字符输出流对象
3:把字符输出流对象指向这个文本文件
为什么一定要释放资源?
做了两件事情,第一件让本是对象变成垃圾,
     第二件通知操作系统释放占用的资源。
flush方法和close方法的区别?
flush:刷新缓冲区,流对象还可以继续使用。
close:先刷新缓冲区,然后释放资源。流对象不可以被使用了。
写入数据的时候,如何追加数据?
通过构造方法可以解决
public FileWriter(String fileName,boolean append)


Demo:FileWriter fw = new FileWriter("a.txt",true);


换行该怎么实现?
不同的软件,换行符的标记识别不一样。
windows识别的换行是\r\n。所以,记事本打开的也必须是\r\n换行。
(2)字符输入流的使用。(掌握)
步骤:
创建字符输入流对象
调用字符输入流对象的read方法
 调用读取方法。
两种:
一次读取一个字符。
int read()
一次读取一个字符数组
int read(char[] chs)
释放资源

代码体现:
FileReader fr = new FileReader("fw.txt");


//方式1
int ch = 0;
while((ch=fr.read())!=-1)
{
System.out.print((char)ch);
}


//方式2
char[] chs = new char[1024];
int len = 0;
while((len=fr.read(chs))!=-1)
{
System.out.print(new String(chs,0,len));
}


fr.close();


问题?
读取数据的时候,文件一定要存在。
(3)案例:(掌握)
复制文本文件加入异常处理。(理解)
复制文本文件。(掌握)


代码体现:
FileReader fr = new FileReader("fr.txt");
FileWriter fw = new FileWriter("fw.txt");


//方式1
int ch = 0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}


//方式2
char[] chs = new char[1024];
int len = 0;
while((len=fr.read(chs))!=-1)
{
fw.write(chs,0,len);
}


fw.close();
fr.close();
(4)字符缓冲流(掌握)
BufferedWriter:
特殊方法:void newLine()
BufferedReader:
特殊方法:String readLine()


复制文本文件:
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));


//方式1
int ch = 0;
while((ch=br.read())!=-1)
{
bw.write(ch);
bw.flush();
}


//方式2
char[] chs = new char[1024];
int len = 0;
while((len=br.read(chs))!=-1)
{
bw.write(chs,0,len);
bw.flush();


}

//方式3
String line = null;
while((line=br.readLine())!=null)
{
bw.write(line);
bw.newLine();
bw.flush();
}


bw.close();
br.close();
day24
1:字节流
(1)与字符流类似。
InputStream
FileInputStream
BufferedInputStream


OutputStream
FileOutputStream
BufferedOutputStream
(2)字节流复制文件
A:复制文本文件
B:复制图片,视频,音频等二进制文件
(3)复制MP3,并测试时间。(四种方式复制mp3所用的时间)


2:转换流
(1)在操作字节流数据的时候,为了使用高效字符流的一些方法,
  需要把字节流进行转换。这个时候java就提供了转换流。
(2)标准的键盘录入和控制台输出流对象
System.in -- InputStream
System.out -- PrintStream -- OutputStream(PrintStream的父类)
(3)字符流的由来
字符流 = 字节流 + 编码表


3:复制数据的操作规律
A:文本文件 -- 文本文件
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt");


String line = null;
while((line=br.readLine())!=null)
{
bw.write(line);
bw.newLine();
bw.flush();
}


bw.close();
br.close();


B:文本文件 -- 控制台输出
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));


String line = null;
while((line=br.readLine())!=null)
{
bw.write(line);
bw.newLine();
bw.flush();
}


bw.close();
br.close();


C:键盘录入 -- 文本文件
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt");


String line = null;
while((line=br.readLine())!=null)
{
//如果数据源是键盘录入,一定要自定义结束标记
if("over".equals(line)
{
break;
}


bw.write(line);
bw.newLine();
bw.flush();
}


bw.close();
br.close();



D:键盘录入 -- 控制台输出
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));


String line = null;
while((line=br.readLine())!=null)
{
//如果数据源是键盘录入,一定要自定义结束标记
if("over".equals(line)
{
break;
}


bw.write(line);
bw.newLine();
bw.flush();
}


bw.close();
br.close();


 规律:
A:明确操作数据源和目的地的体系
数据源:
从数据源是读取数据
InputStream
Reader
目的地:
把数据写入到目的地
OutputStream
Writer


B:明确具体的数据源和目的地是否是文本文件
数据源:
是:Reader
不是:InputStream
目的地:
是:Writer
不是:OutputStream


C:明确操作的具体的数据所在地
数据源:
硬盘上的文本文件 FileReader
键盘录入数据(System.in) InputStream -- InputStreamReader
目的地:
硬盘上的文本文件 FileWriter
控制台输出(System.out) OutputStream -- OutputStreamWriter


FileReader
FileWriter
InputStreamReader
public InputStreamReader(InputStream in)创建一个使用默认字符集的 InputStreamReader。


字符流 = 字节流 + 编码表;


InputStreamReader
OutputStreamWriter


D:是否使用高效
是:用带Buffered流对象
不是:不用带Buffered流对象


BufferedReader br = new BufferedReader(数据源);
BufferedWriter bw = new BufferedWriter(目的地);


String line = null;
while((line=br.readLine())!=null)
{
//如果数据源是键盘录入,一定要自定义结束标记
if("over".equals(line)
{
break;
}


bw.write(line);
bw.newLine();
bw.flush();
}


bw.close();
br.close();
day25
打印流(掌握)
(1)打印流只能是写数据。它对字节和字符都提供多种打印数据的方式。
(2)特点:
A:可以打印任意类型的数据
B:能够自动刷新数据,并换行
前提:启动自动刷新,并使用println,printf,format方法
C:它是可以直接操作设备(文件)的流对象
如果一个流对象的构造方法同时提供了File和String的构造,
那么它就是可以直接操作设备的流对象。
(3)操作
A:write方法的使用
B:print方法的使用
C:println方法的使用
代码体现:复制文本文件

BufferedReader br = new BufferedReader(new FileReader("a.txt"));
// 创建打印流,并启动刷新
PrintWriter pw = new PrintWriter(new FileWriter("pw.txt"),true);


String line = null;
while((line=br.readLine())!=null)
{
pw.println(line);//三个操作:1写入数据2换行3自动刷新
}


pw.close();
br.close();
Properties(掌握)
(1)是属于Map体系的集合对象。一般用于操作属性文件,键和值都是字符串。
(2)特殊方法
A:list 保存数据
void list(PrintStream ps)
void list(PrintWriter pw)
B:load 加载数据
void load(InputSteram is)
void load(Reader r)
C:store 保存数据
void store(OutputStream os,String s)
void store(Writer w,String s)
(3)案例:(掌握)
从prop.txt文件中找有没有键值为lisi的数据,如果有,则修改其值为100
注:HashSet,底层HashMap  set.add("a")其实底层做了这个操作map.put("a",new Object());其中new Object()是没有意义的数。


网络编程:


1:网络编程(理解)
(1)网络编程 用java实现多台计算机间的数据通信。
(2)网络编程的三要素(掌握)
A:IP地址
B:端口号
逻辑端口。用于标识应用程序的进程。
范围:0-65535  
C:协议
UDP:发送数据包,数据有大小限制。
   不需要建立连接,速度快,但是不可靠。
TCP:建立连接通道,数据没有限制。
   速度慢,但是可靠。
(3)Socket概述(理解)
Socket是为实现网络编程提供的一种流机制。
数据的传输就是在Socket之间进行传输。
(4)UDP程序(掌握)
发送端:
A:创建发送端Socket对象
B:把数据打包
C:发送数据
D:释放资源


代码体现:
DatagramSocket ds = new DatagramSocket();


byte[] bys = "hello,udp";
DatagramPacket dp = new DatagramPacket(bys,bys.length,
InetAddress.getByName("192.168.1.100"),10000);


ds.send(dp);


ds.close();

接收端:
A:创建接收端Socket对象
B:创建数据包接收数据
C:解析数据包
D:释放资源

代码体现:
DatagramSocket ds = new DatagramSocket(10000);


byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);

ds.receive(dp):


String text = new String(dp.getData(),0,dp.getLength());
System.out.println(text);


ds.close();
(5)TCP程序(掌握)
客户端:
A:创建客户端Socket对象
B:获取输出流
C:写数据
D:释放资源


代码体现:
Socket s = new Socket(InetAddress.getByName("192.168.1.1"),10000);

OutputStream os = s.getOutputStream();
os.write("hello,tcp".getBytes());

s.close();


服务器端:
A:创建服务器端Socket对象
B:监听并获取当前连接的客户端对象
C:获取输入流
D:读数据
E:释放资源


代码体现:
ServerSocket ss = new ServerSocket(10000);


Socket s = ss.accept();


InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String client = new String(bys,0,len);
System.out.println("client:"+client);


s.close();
ss.close();
(6)案例
A:UDP聊天程序
B:TCP服务器给反馈的案例
C:TCP键盘录入数据案例




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值