//声明方式:类型[] 变量;
//数组的创建:new 类型[容量];
String[] names = new String[10];
// 给数组添加数据,添加的方式为:数组变量[索引] = 数据;
// 添加数据和访问数据时,索引不能超过指定范围(0~length-1)
// 重复给相同索引添加数据,等同于修改
names[0]="zhangsan";
// 查询(访问)数据的方式:数组变量[索引];
System.out.println(names[0]);
//对象数组
User[] user = new User[3];
for(int i = 0;i<3;i++)//可以直接用 user.length替换3
{
user[i] = new User;
}
for(int i = 0;i<3;i++)
{
user[i].test();
}
Java中的二维数组更像是一种引用,并不是严格的方阵
String[][] nums = new String[3][3];
1.
String s = "Hello World";
//子字符串
s.substring(0,3);//从第一个字符开始,到下标为3的字符,但不包括该位置
/*
substring 方法用于截取字符串,需要传递两个参数:
第一个参数表示截取字符串的起始位置(索引,包含)
第二个参数表示截取字符串的结束位置(索引,不包含)
*/
s.substring(0,"Hello".length);//截取Hello
2.
s.substring(6);
//只传递一个参数表示从指定位置开始截取字符串,然后截取到最后
返回数组
//根据指定的规则对字符串进行分解,可以将一个完整的字符串,分解成几部分
String[] s1 = s.split(" ");
去掉字符串的首位空格,字符串中间的空格不做处理
String s=" hh hh ";
sout(s.trim());
==>hh hh
纯粹的替换
String s = "Hello World";
s.replace("World","java");
按照规则替换
String s = "Hello World Zhangsan";
s.replace("World|Zhangsan","java");//将World与Zhangsan都替换成java
s.toLowerCase();//全部转小写
s.toUpperCase();//全部转大写
char[] chars = s.toCharArray();//将字符串拆分成字符数组
byte[] bytes = s.getBytes("UTF-8");//将字符串拆分成utf-8字节码
s.charAt(索引号);//传递索引定位字符串中指定位置的字符
s.indexOf(" ");//用于获取数据在字符串中第一次出现的位置
s.lastIndexOf(" ");//用于获取数据在字符串中最后一次出现的位置
s.contains(" ");//用于判断字符串中有没有出现过该数据,boolean类型
s.startsWith(" ")//判断字符串是否以指定的数据开头,boolean类型
s.endsWith("");//判断字符串是否以指定数据结尾,boolean类型
s.isEmpty();//判空,boolean,空格是特殊的字符,不为空
是一个类,在底层用数组的形式存储字符串,防止一遍遍的拼接字符串效率低
自带方法
append:加入
length:求长度
reverse:反转
insert(位置,字符串):插入
StringBuilder s = new StringBuilder();
for(int i = 0;i<100;i++)
{
s.append(i);
}
System.out.println(s.toString());
Byte 、 Short、Integer、Long、Float、Double、Character、Boolean
基本类型与包装类型互转
int i = 10;
Integer i1;
i1=i;
int i2 = i1.intValue();//包装向普通转
//可自动拆箱
i2 = i1; 也对
回顾基本数据类型
byte short int long float double char boolean
* y(Y) 年->yyyy Y表示一年有52周,大于52周的转到下一年
* m(M) MM:月份 mm:表示分钟
* d(D) dd:一个月中的日期 D:一年中的日期
* h(H) hh:12进制 HH:24进制
* s(S) ss:秒 SSS:毫秒
//Date :日期类
//Calendar:日历类
输出从1970年1月1日到现在的时间戳:毫秒数
System.currentTimeMillis()
Date date = new Date();
// Java日期格式化:
/*
* y(Y) 年->yyyy Y表示一年有52周,大于52周的转到下一年
* m(M) MM:月份 mm:表示分钟
* d(D) dd:一个月中的日期 D:一年中的日期
* h(H) hh:12进制 HH:24进制
* s(S) ss:秒 SSS:毫秒
*
* */
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String dateFormatString = dateFormat.format(date); //日期转字符串
System.out.println(dateFormatString);
PreparedStatement 类继承自 Statement 类,在 JDBC 开发中用来取代前者。有以下两个优势:
- 可对 SQL 语句进行预编译,可以灵活地修改 SQL 语句,提高开发效率。
- 把用户输入单引号转义,防止恶意注入,保护数据库安全。
Connection connection = DriverManager.getConnection();
String sql = "INSERT INTO test(id,name) VALUES (?,?)";
PreparedStatement stmt = connection.preparedStatement(sql); // 创建对象并预编译
stmt.setInt(1, 755); // 在第一个占位符(?)位置插入数字
stmt.setString(2, "MrJoker"); // 在第二个占位符(?)位置插入字符串
stmt.executeUpdate(); // 更新并执行
PreparedStatement 类可以通过 executeBath 方法批量处理 SQL 语句,进一步提高效率。其返回值为一个 int[] 数组。
Connection connection = DriverManager.getConnection();
String sql = "INSERT INTO test(id,name) VALUES (?,?)";
PreparedStatement stmt = connection.prepareStatement(sql);
for (int i = 1; i <= 1000; i++) {
stmt.setInt(1, i);
stmt.setString(2, (i + "号士兵"));
stmt.addBatch(); // 语句添加到批处理序列中
}
preparedStatement.executeBatch(); // 语句发送给数据库批量处理
preparedStatement.clearBatch(); // 清空批处理序列
ResultSet rs = stmt.executeQuery(sql); // 获取返回结果
while(rs.next()){ // 输出返回结果
System.out.println(rs.getString("area_id"));
}
java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造器 … …
当方法执行抛出异常时,必须由专门的代码块对异常进行处理。
注意事项
如果 try 语句中出现的异常未被 catch,默认将异常 throw 给上层调用者处理。但必须在方法中声明 throws。
try/catch 代码中的 return 语句会在执行完 finally 后再返回,但 finally 中对返回变量的改变不会影响最终的返回结果。
finally 代码中应避免含有 return 语句或抛出异常,否则只会执行 finally 中的 return 语句,且不会向上级抛出异常。
Java 7 后在 try 语句中打开 IO 流,会在跳出后自动关闭流。不必再用 finally 语句关闭。
class TestException{
public void writeList(int size) {
PrintWriter out = null;
try {
if(size < 1) throw new IndexOutOfBoundsException("至少要输出1个字符");
out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < size; i++)
System.out.println("Value at: " + i + " = " + list.get(i));
} catch (IndexOutOfBoundsException e) {
System.err.println("Caught IndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} finally {
if (out != null) out.close();
}
}
}
【列表】元素有序,可以按照索引进行操作 获取时下标从0开始
在相同索引位置进行add操作,则该位置的索引会顺势后移,并不会替换该位置元素即索引号与位置并非一一对应。
// 修改
list.add("data1"); // 末尾添加元素
list.add(0, "data0"); // 插入元素
list.remove(0); // 按索引删除元素(int)
list.remove("data"); // 按内容删除对象元素(Object)
list.remove(new Integer(3)); // 按内容删除基础类型元素
list.clear(); // 清除所有元素
list.set(0, "data2"); // 修改元素
// 查找
list.isEmpty(); // 判定是否为空
list.size(); // 查询列表元素个数
list.contains("data3"); // 判定是否含有元素
list.get(1); // 按索引查找元素
list.indexOf("data1"); // 查询索引号:如果有返回第一个,没有返回-1
list.lastIndexOf("data1"); // 查询索引号:如果有返回最后一个,没有返回-1
// 转化
list.toString(); // 转化为字符串
list.toArray(); // 转化为 Object[] 数组
(String [])list.toArray(); // 转化为对象数组,但不能是基础类型
【集】数据不可重复。
// 修改
set.add("data"); // 添加元素
set.remove("data"); // 删除元素
set.clear(); // 清除所有元素
// 查询
set.get(1); // 按序号查找元素(仅限于有序的 set 接口)
set.isEmpty(); // 判断是否为空
set.size(); // 返回元素个数
set.contains("data"); // 判定是否含有元素Copy to clipboardErrorCopied
HashSet 类无序,因此不支持 get 方法:获取对象必须要通过 Iterator 来遍历。
Collections 类是针对集合类的一个帮助类,他提供一系列静态方法实现各种集合操作。
Collections.swap(list, 1, 2); // 元素交换顺序
Collections.shuffle(list); // 元素随机排序
Collections.reverse(list); // 元素颠倒排序
Collections.sort(list); // 元素按大小排序,可以自定义比较顺序
Collections.rotate(list, 2); // 元素右移指定长度
Collections.binarySearch(list, "data"); // 二分查找元素索引,只适用于有序集合
Collections.max(list); // 返回最大元素,可以自定义比较顺序
Collections.min(list); // 返回最小元素,可以自定义比较顺序
Collections.frequency(list, "data"); // 返回对象出现次数
Collections.fill(list, "data"); // 使用指定元素填充
Collections.replaceAll(list, "old", "new"); // 使用指定元素替换
调用 Collections 类中的 synchronizedList 方法,可以将 List 接口转换成线程安全的容器使用。
List 接口中的方法都会被添加 synchronized 锁(效率不高)。但是 iterator 方法没有加锁,如果要遍历还需要在外层加锁。
List list = Collections.synchronizedList(new ArrayList());
synchronized (list) {
Iterator i = list.iterator();
while (i.hasNext())
foo(i.next());
}
【数组序列】实现了 List 接口,内部使用 Object 数组存储:
ArrayList 构造方法
List<Integer> list = new ArrayList<>(); // 默认初始容量为 10
List<Integer> list = new ArrayList<>(100); // 自定义初始容量
List<Integer> list = new ArrayList<>(queue); // 构造时直接复制其他容器元素(可以是任何 Collection 类)
List list = new ArrayList(); // 未指定元素类型则为 Object 类
【哈希表】 实现 Map 接口。底层使用散列存储:构造一个 Entry 数组,根据 key 的 hash 值将 Entry 存入指定位置。
HashMap 构造方法
注:Map
Map<String,Integer> map = new HashMap<>(); // 默认初始容量 16 负载因数 0.75
Map<String,Integer> map = new HashMap<>(32); // 自定义初始容量
Map<String,Integer> map = new HashMap<>(32, 0.5f); // 自定义初始容量和负载因数
语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。
//一个参数无返回
NoReturnOneParam noReturnOneParam = (int a) -> {
System.out.println("NoReturnOneParam param:" + a);
};
noReturnOneParam.method(6);
//一个参数有返回值
ReturnOneParam returnOneParam = (int a) -> {
System.out.println("ReturnOneParam param:" + a);
return 1;
};
int res2 = returnOneParam.method(6);
System.out.println("return:" + res2);
import lambda.interfaces.*;
public class Test2 {
public static void main(String[] args) {
//1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
NoReturnMultiParam lamdba1 = (a, b) -> {
System.out.println("简化参数类型");
};
lamdba1.method(1, 2);
//2.简化参数小括号,如果只有一个参数则可以省略参数小括号
NoReturnOneParam lambda2 = a -> {
System.out.println("简化参数小括号");
};
lambda2.method(1);
//3.简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号
NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
lambda3.method();
//4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
ReturnOneParam lambda4 = a -> a+3;
System.out.println(lambda4.method(5));
ReturnMultiParam lambda5 = (a, b) -> a+b;
System.out.println(lambda5.method(1, 1));
}
}
有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用 lambda表达式的接口快速指向一个已经被实现的方法。
**语法:**方法归属者::方法名 其中静态方法的归属者为类名,普通方法归属者为对象
//lambda2 引用了已经实现的 doubleNum 方法 ,doubleNum为静态方法
ReturnOneParam lambda2 = Exe1::doubleNum;
System.out.println(lambda2.method(3));
Exe1 exe = new Exe1();
//创建exe对象是为了实现非静态方法
//lambda4 引用了已经实现的 addTwo 方法
ReturnOneParam lambda4 = exe::addTwo;
System.out.println(lambda4.method(2));
一般我们需要声明接口,该接口作为对象的生成器,
通过 类名::new 的方式来实例化对象,然后调用方法返回对象。
interface ItemCreatorBlankConstruct {
Item getItem();
}
interface ItemCreatorParamContruct {
Item getItem(int id, String name, double price);
}
public class Exe2 {
public static void main(String[] args) {
ItemCreatorBlankConstruct creator = () -> new Item();
Item item = creator.getItem();
ItemCreatorBlankConstruct creator2 = Item::new;
Item item2 = creator2.getItem();
ItemCreatorParamContruct creator3 = Item::new;
Item item3 = creator3.getItem(112, "鼠标", 135.99);
}
}
forEach的三种用法:
//1.直接forEach遍历
for(int i:list){ System.out.println(i); }
//2.用system.out::prinimport lambda.interfaces.*;
public class Test2 {
public static void main(String[] args) {
//1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
NoReturnMultiParam lamdba1 = (a, b) -> {
System.out.println("简化参数类型");
};
lamdba1.method(1, 2);
//2.简化参数小括号,如果只有一个参数则可以省略参数小括号
NoReturnOneParam lambda2 = a -> {
System.out.println("简化参数小括号");
};
lambda2.method(1);
//3.简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号
NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
lambda3.method();
//4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
ReturnOneParam lambda4 = a -> a+3;
System.out.println(lambda4.method(5));
ReturnMultiParam lambda5 = (a, b) -> a+b;
System.out.println(lambda5.method(1, 1));
}
}tln
list.forEach(System.out::println);
//3.有map集合 键值对的情况下
set.forEach((key) -> {
System.out.println(key + "\t"+map.get(key));
});
JDK 1.8 新增。将要处理的元素集合看作一种流,在管道的节点上进行处理。使代码更简洁易读。
集合接口有两个方法来生成流,数据类型将由 Collection 转化为 Stream 。
stream
方法:为集合创建串行流。parallelStream
方法:为集合创建并行流。parallel
和 sequential
方法相互转化。Stream<Integer> stream = list.stream(); // 声明作为流处理
ParellerStream<Integer> pStream = stream.parallel(); // 转化为并行流
流处理的每个操作阶段都会封装到一个 Sink 接口里,处理数据后再将数据传递给下游的 Sink。
Stream 上的所有操作分为两类:中间操作和结束操作。Stream 是延迟执行的,只有调用到结束操作,才触发整个流水线的执行。如果未定义结束操作,那么流处理什么也不会做。
// 获取空字符串的数量
int count = strings.parallelStream() // 声明作为流处理
.filter(string -> string.isEmpty()) // 中间操作,过滤空元素
.count(); // 结束操作,计数
map
方法用于映射每个元素到对应的结果,其实就是对结果进行转化。
// 获取对应的平方数
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());Copy to clipboardErrorCopied
filter
方法用于通过设置的条件过滤出元素。
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();Copy to clipboardErrorCopied
limit
方法用于获取指定数量的流(前 n 个), skip
方法用于去除指定数量的流(前 n 个)。
// 筛选出 11-20 条数据
Random random = new Random();
random.ints().limit(20).skip(10).forEach(System.out::println);Copy to clipboardErrorCopied
sorted
方法通过 Comparable 接口对流进行排序,也可以自定义。
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);Copy to clipboardErrorCopied
distinct
方法通过流元素的 hashCode 和 equals 方法去除重复元素。
Random random = new Random();
random.ints().distinct().forEach(System.out::println);
在 Java 程序中所创建的对象都保存在内存中,一旦 JVM 停止运行,这些对象都将会消失。因此以下两种情况必须通过序列化实现:
在类中声明实现 Serializable 接口,表示允许 Java 程序对这个类的对象序列化:JVM 会将对象的成员变量保存为一组字节,这些字节可以再被 JVM 组装成对象。对象序列化只保存的对象的成员变量,且不会关注类中的静态变量。
//person类的读入读出
//对于 class Person implements Serializable
ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(file));
Person person = new Person("John", 101, Gender.MALE);
oout.writeObject(person);
oout.close();
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));
Object newPerson = oin.readObject(); // 没有强制转换到Person类型
oin.close();
读取标准输入设备数据(键盘),每次输入将以换行符结束。数据类型为 InputStream。
char c = (char)System.in.read(); // 读取单个输入字符,返回其 ASCII 值(int)
byte[] b = new byte[20];
System.in.read(b); // 读取输入定长字符组,返回字符个数(int)
向标准输出设备输出数据(控制台)。数据类型为 PrintStream。
System.out.print("hello"); // 输出数据
System.out.println("hello"); // 输出数据并换行
通过 printf 方法可以输出指定格式数据:其中 %d
表示整型数字, %f
表示浮点型数字, %%
表示百分号。
在百分号后加入特殊符号,可以指定数据的显示类型。
符号 | 作用 | 示例 | 效果 |
---|---|---|---|
+ | 为正数或者负数添加符号 | (“%+d”,99) | +99 |
2 | 位数(默认右对齐) | (“%4d”, 99) | __99 |
− | 左对齐 | (“%-4d”, 99) | 99__ |
0 | 数字前补0 | (“%04d”, 9999) | 0099 |
, | 以“,”对数字分组 | (“%,d”, 9999) | 9,999 |
.2 | 小数点后精确位数 | (“%5.2f”, 9.999) | _9.99 |
以字节为单位进行读取的数据流。常用来处理二进制数据的输入输出,如键盘输入、网络通信。但字节流不能正确显示 Unicode 字符。
输入流
InputStream in = new InputStream(socket.getIntputStream()); // 创建输入对象
int len = in.available(); // 读取输入对象长度
char c = (char)in.read(); // 读取输入字节
byte[] b = new byte[len]; // 连续读取输入字节
in.read(b);
in.close(); // 关闭输入对象Copy to clipboardErrorCopied
输出流
OutputStream out = new OutputStream(socket.getOutputStream()); // 创建输出对象
byte[] b = {1,2,3}; // 导入输出字节
out.write(b);
out.flush(); // 刷新输出对象,输出字节
out.close(); // 关闭输出对象,输出字节
以字符为单位进行读取的数据流。只能用于处理文本数据。且所有文本数据,即经过 Unicode 编码的数据都必须以字符流的形式呈现。
我们在 Java 程序中处理数据往往需要用到字符流,但在通信中却需要使用字节流。这就需要进行数据格式转化。
Reader 类子类。将字节流数据转换成字符流,常用于读取控制台输入或读取网络通信。可指定编码方式,否则使用 IDE 默认编码方式。
// 读取键盘输入
InputStreamReader in = new InputStreamReader(System.in);
// 读取套接字通信,并指定编码格式
InputStreamReader in = new InputStreamReader(socket.getInputStream(), "UTF-8");Copy to clipboardErrorCopied
Writer 类子类。将字符流数据转换成字节流,常用于发送网络通信。
// 数据转化为字节流发送
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());Copy to clipboardErrorCopied
用于文件或者目录的描述信息,默认加载当前目录。
File f1 = new File("FileTest.txt"); // 读取当前目录文件
File f2 = new File("D://file//FileTest.txt"); // 读取指定目录文件Copy to clipboardErrorCopied
FileInputStream 类读取字节流文件信息,FileReader 类读取字符流文件信息。
public class TestFileReader {
public static void ReadFile(String textName) {
int c = 0;
try {
// 连接文件
FileReader fr = new FileReader("D:\\Workspaces" + textName);
// 执行操作
while ((c = fr.read()) != -1) {
System.out.print((char)c);
}
fr.close();
} catch (FileNotFoundException e) {
System.out.println("找不到指定文件");
} catch (IOException e) {
System.out.println("文件读取错误");
}
}
}Copy to clipboardErrorCopied
FileOutputStream 写入字节流文件信息,FileWriter 类写入字符流文件信息。
public class TestFileWriter {
public static void ReadFile(String textName) {
int c = 0;
try {
// 追加模式,写入文本信息会添加到文本尾部
FileWriter fw = new FileWriter(textName);
// 覆盖模式,写入文本信息会覆盖原有数据
FileWriter fw2 = new FileWriter("data.txt", false);
// 执行操作
fw.write("Hello world!欢迎来到 java 世界\n");
fw.append("我是下一行");
fw.flush();
System.out.println("文件编码为" + fw.getEncoding());
fw.close();
} catch (FileNotFoundException e) {
System.out.println("找不到指定文件");
} catch (IOException e) {
System.out.println("文件写入错误");
}
}
}Copy to clipboardErrorCopied
BufferedInputStream 类将输入字节数据暂存到缓冲区数组,BufferedReader 类将输入字符流数据暂存到缓冲区数组。
JVM 在缓冲区数组满后一次性获取缓冲区内的数据,减少了对 CPU 的频繁请求。
BufferedOutputStream 类将输出字节数据暂存到缓冲区数组,BufferedWriter 类将输出字符流数据暂存到缓冲区数组。
JVM 在刷新时一次性将缓冲区内的数据输出到外部设备,减少了对 CPU 的频繁请求。
class TestBuffer{
public static void bufferUse() throws IOException {
// 通过缓冲区读取键盘输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 通过缓冲区输出到文件
BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"));
// 执行操作
String line = null;
while((line = br.readLine()) != null){ // readLine 缓冲流特有方法,一次性读取一行
if("over".equals(line)){
break;
}
bw.write(line);
bw.newLine(); // newLine 缓冲流特有方法,写入换行符
bw.flush();
}
bw.close();
br.close();
}
}