可变参数:
就是一种特殊的形参,定义在方法,构造器的形参列表中,格式为:数据类型...参数名称;
好处:可以不传数据给它,也可以传一个或多个数据给它,还可以传一个数组给它
常常用来灵活地接收数据
一个形参列表里无论数据类型如何,只能有一个可变参数,若有其他参数就需要将可变参数放在最后
public static void test(int age,int...number){
System.out.println(number.length);
System.out.println(Arrays.toString(number));//可变参数就是数组
}
test(1);
test(1);
test(1,2,3,4);
test(1,new int[]{10,20,30,40});
collections:
collections是一个用来操纵集合的工具类,
addAll
添加一批数据的API
List<String> names=new ArrayList<>();
Collections.addAll(names,"A","B","C");//批量添加元素
System.out.println(names);//[A, B, C]
shuffle
打乱List集合的顺序
Collections.shuffle(names);//打乱元素顺序
System.out.println(names);//[C, A, B]
sort
sort方法:参考之前Arrays中sort的用法(重写compareto方法)( 在后面创建比较器对象)
只支持List系列集合
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o1.getHeight(),o2.getHeight());
}
});
Map系列集合:
Map集合称之为双链集合,格式:【Kay1=value1,Kay2=value2,Kay3=value3,Kay4=value4,....】一次需要存一对数据为一个元素
Map集合的每个元素“key=value”称之为一个键值对/键值对对象/一个Entry对象,Map集合也被叫做"键值对集合"
***map集合的所有键不能重复但对于值不做要求
Map集合对于相同的键,后加覆盖前加;
原本的Set集合就是基于Map实现的,只是它不要值,只要键
Map集合底层是基于哈希表实现的
HashMap由键决定特点,无序不重复,无索引
LinkedHashMap由键决定特点,有序,不重复,有索引
TreeMap由键决定特点,按大小默认升序排列,不重复,无索引
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<>();
map.put("手表",100);
map.put("手表",200);
map.put(null,null);
map.put(null,1);
map.put("手机",null);
System.out.println(map);//{手表=200}//键不能重复,后加覆盖前加
//{null=1, 手表=200, 手机=null}
//键和值任意一个不为null都会输出
}
size()
获取键值对的数量
Map<String,Integer> map=new HashMap<>();
map.put("手表",220);
map.put("手表",250);
map.put("手机",100);
map.put("电脑",500);
System.out.println(map);
//size(获取键值对数量)
System.out.println(map.size());//3
clear()
清空Map集合中的元素
map.clear();
isimpty()
判断集合是否为空,为空则返回true反之false
Map<String,Integer> map1=new HashMap<>();
map1.put(null,1);
Map<String,Integer> map2=new HashMap<>();
map2.put("小明",null);
Map<String,Integer> map3=new HashMap<>();
map3.put(null,null);
System.out.println(map1.isEmpty());//false
System.out.println(map2.isEmpty());//false
System.out.println(map3.isEmpty());//false
Map<String,Integer> map4=new HashMap<>();
map4.put("",null);
System.out.println(map4.isEmpty());//false
以上代码证明null不会相应isimpty()
get()
根据键获得(返回)对应的值
int v1=map.get("手表");
System.out.println(v1);//250
System.out.println(map.get("手机"));//100
remove()
根据键删除整个元素并返回这个元素的值
containskey()
判断是否包含某个键,包含返回true反之返回false
containsvalue()
判断是否包含某个值,包含返回true反之返回false
keyset()
获取map集合中全部的键
values()
获取map集合中全部的值
putAll()
复制一份倒入,后加覆盖前加
Map<String,Integer> map5=new HashMap<>();
map5.put("java1",10);
map5.put("java2",20);
Map<String,Integer> map6=new HashMap<>();
map6.put("java3",10);
map6.put("java2",220);
map5.putAll(map6);
System.out.println(map5);//{java3=10, java2=220, java1=10}
System.out.println(map6);//{java3=10, java2=220}
put()==add()
Map集合的遍历
Map<String,Integer> map = new HashMap<>();
map.put("手表",250);
map.put("手机",100);
map.put("电脑",500);
map.put("sb校园网",250);
System.out.println(map);//{手表=250, 电脑=500, 手机=100, sb校园网=250}
//1.获取map集合中的全部键
//1.获取map集合中的全部键
Set<String> keys=new HashSet<>();
keys=map.keySet();
System.out.println(keys);
//遍历全部键,根据键获取对应的值
增强for
//增强for循环
for (String key : keys) {
int value= map.get(key);
System.out.println(key+"="+value);
}
entryset()
获取所有的键值对集合,把Map集合转换成entrySet的键值对类型
Set<Map.Entry<String, Integer>> entries = map.entrySet();
System.out.println(entries);
for (Map.Entry<String, Integer> entry : entries) {//Entry接口提供了getkey和getvalue方法
String key=entry.getKey();
int value=entry.getValue();
System.out.println(key+"==>"+value);
}
Lambda表达式遍历
map.forEach((k,v)->{
System.out.println(k+"----->"+v);
});
HashMap
由键决定特点,无序不重复,无索引
public static void main(String[] args) {
Map<Student, String> map = new HashMap<>();
map.put(new Student("小明",18,182.2),"花果山");
map.put(new Student("小绿",19,158.2),"灵山");
map.put(new Student("小傻",10,166.2),"狮驼岭");
map.put(new Student("傻b校园网",250,250.0),"何科原");
map.put(new Student("傻b校园网",250,250.0),"学院");
System.out.println(map);
//在没有重写hashcode和equals时,两个傻b校园网都被输出
//重写后只有后面那个傻b校园网被输出
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Double.compare(height, student.height) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
Generate里面有重写该集合的快速方式
LinkedHashMap
有序,不重复,无索引
Map<String,Integer> map = new LinkedHashMap<>();
map.put("手表",250);
map.put("手机",100);
map.put("电脑",500);
map.put("sb校园网",1250);
map.put("sb校园网",2250);
map.put("sb校园网",3250);
map.put("sb校园网",4250);
System.out.println(map);
Map<Student, String> map1 = new LinkedHashMap<>();
map1.put(new Student("小明",18,182.2),"花果山");
map1.put(new Student("小绿",19,158.2),"灵山");
map1.put(new Student("小傻",10,166.2),"狮驼岭");
map1.put(new Student("傻b校园网",250,250.0),"何科原");
map1.put(new Student("傻b校园网",250,250.0),"学院");
System.out.println(map1);
//在没有重写hashcode和equals时,两个傻b校园网都被输出
//重写后只有后面那个傻b校园网被输出
在没有重写hashcode和equals时,两个傻b校园网都被输出
上面那句话证明了同内容的对象哈希值不一定相同
TreeMap
有序(按默认大小升序排列),不重复,无索引
Map<Student,String> map=new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o1.getHeight(),o2.getHeight());
}
});
集合的嵌套:
集合中的元素还是一个集合
例如:
Map<String, List<String>> map=new HashMap<>();
这个Map集合的值为List集合,
这样就可以用可变参数来批量添加数据
List<String> cities1=new ArrayList<>();
Collections.addAll(cities1,"南京市","苏州市","无锡市");
map.put("江苏省",cities1);
Stream流
Stream也叫Stream流,是JDK8开始新增的一套API,用来操纵集合或数组中的数据的
Stream流大量结合了Lambda语言风格来编译提供了一种更加强大更加简单的方法来操纵集合或数组中的数据
获取List集合的Stream流
List<String> list=new ArrayList<>();
list.add("张无忌");
list.add("张三丰");
list.add("张角");
list.add("张梁");
list.add("张宝");
list.add("诸葛亮");
List<String> list1=list.stream().filter(s ->s.startsWith("张")).filter(a -> a.length()==2).collect(Collectors.toList());
System.out.println(list1);
获取Set集合的Stream流
Set<String> set=new HashSet<>();
set.add("张无忌");
set.add("张三丰");
set.add("张角");
set.add("张梁");
set.add("张宝");
set.add("诸葛亮");
set.stream().filter(s->s.startsWith("张")).forEach(s-> System.out.println(s));
获取Map集合的Stream流
Map<String,Integer> map=new HashMap<>();
map.put("手表",250);
map.put("手机",100);
map.put("电脑",500);
map.put("sb校园网",250);
Set<String> keys=map.keySet();
Collection<Integer> values = map.values();
Stream<String> skeys = keys.stream();
Stream<Integer> svalues = values.stream();
skeys.filter(s->s.startsWith("sb")).forEach(s-> System.out.println(s));
Set<Map.Entry<String, Integer>> entries = map.entrySet();
entries.stream().forEach(s-> System.out.println(s));
获取数组的Stream流
String[] name2={"熊大","熊二","光头强","吉吉","毛毛"};
Stream<String> sn1 = Arrays.stream(name2);
Stream<String> sn2 = Stream.of(name2);
中间方法:
中间方法:filter,sorted,limit,skip,map,distinct,concat(调用后返回新的stream流,可以直接继续使用)
students.add(new Student("李华",18,1222.5));
//students.add(new Student("李华",18,1222.5));
students.add(new Student("大明",148,7561));
students.add(new Student("大宝",222333,23333));
students.add(new Student("大贵",1,561));
students.add(new Student("大牛",48,756));
找出年龄大于等于18小于等于100的学生,并按照年龄降序排列
sorted排序方法
students.stream().filter(s->s.getAge()>=18&&s.getAge()<=100).sorted(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o1.getHeight(),o2.getHeight());
}
}).forEach(s-> System.out.println(s));
去除身高最高的三名学生并输出
Limit限制取出的元素的最高个数
students.stream().sorted((o1,o2) ->Double.compare(o2.getHeight(),o1.getHeight()))
.limit(3).forEach(s-> System.out.println(s));
取出身高倒数的两名学生并输出
skip(n)跳过前n个要输出的元素
students.stream().sorted((o1,o2) ->Double.compare(o2.getHeight(),o1.getHeight()))
.skip(students.size()-2).forEach(s-> System.out.println(s));
找出身高超过1000的学生的名字,重复的去重复
distinct去重复
students.stream().filter(s->s.getHeight()>1000).map(s->s.getName()).distinct().forEach(System.out::println);
concat将两个流合并成一个流
Stream<String> st1=Stream.of("张三" ,"李四");
Stream<String> st2=Stream.of("王五");
Stream<String> concat = Stream.concat(st1, st2);
如果和并的两个流数据类型不一样那么合并出来的流必须是object类型的
终结方法:
终结方法:forEach,count,max,min,不返回stream,结束stream流
count统计此流运算后的元素个数,可以重复
long count = students.stream().filter(s -> s.getHeight() > 1000).count();
max获取某项数据最高的元素
Student st3 = students.stream().max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
min获取某项数据最低的元素
Student st3 = students.stream().max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
收集stream流:collect,toArray
collect把流处理的结果放到指定的集合中去
List<Student> l = students.stream().filter(s -> s.getHeight() > 1000).collect(Collectors.toList());
放入Map集合中去
Map<String, Double> map = students.stream().filter(s -> s.getHeight() > 1000).collect(Collectors.toMap(a -> a.getName(), a -> a.getHeight()));
toArray放入数组中:
Object[] arr = students.stream().filter(s -> s.getHeight() > 1000).toArray();
放入Student型的数组中
Student[] arr1 = students.stream().filter(s -> s.getHeight() > 1000).toArray(len -> new Student[len]);
Fire:
File是java.io包下的程序,用于代表当前操作系统的文件(文件,文件夹)
但是file并不具备读入数据的功能
创建对象:
File file = new File("D:\\code\\HelloWorld.java");
fire可以指向一个不存在的路径
File file1 = new File("D:\\code\\nishizhenniubi.java");
System.out.println(file1.length());//找不到对应文件会输出0
System.out.println(file1.exists());//看看寻找的路径到底存不存在,返回true或者false
createNewFile:
创建出不存在的文件
file.createNewFile();//把不存在的文件创建出来
绝对路径:
以上使用的路径均为绝对路径即带盘符的路径
这样的路径在自己的电脑上可以正常使用,但传到他人电脑上,他人可能将文件存入另一个盘符中去,这样绝对路径就失效了
相对路径:
不带盘符,默认去工程下寻找该文件
可以在不同电脑上使用,不用担心上述问题
File file1 = new File("D:\\code\\nishizhenniubi.java");//这是绝对路径
File file2 = new File("nishizhenniubi.java");//这是相对路径
File Method:
创建对象,指代某个文件
File file = new File("D:\\code\\HelloWorld.java");
exists,判断当前路径对象,文件是否存在,存在则返回true
System.out.println(file.exists());
isfile,判断当前文件对象指代的是否是文件,是则返回true
System.out.println(file.isFile());
isDirectory,判断当前文件对象指代的是否是文件夹,是则返回true
System.out.println(file.isDirectory());
getName。获取文件名
System.out.println(file.getName());
length()。获取文件的字节数
System.out.println(file.length());
lostModified,获取文件的最后修改时间
long l = file.lastModified();
SimpleDateFormat time=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
System.out.println(time.format(l));
getPath()获取创建文件对象时使用的路径
System.out.println(file.getPath());
getAbsolutePath获取绝对路径
System.out.println(file.getAbsoluteFile());
创建文件和删除文件相关的常用方法
creatNewFile
创建成功返回true反之(若没有该文件则会创建该文件并返回true,若有该文件则会返回false)
会抛出异常让你检查是否正确
File fire1=new File("D:\\code\\aaa");
System.out.println(fire1.createNewFile());
创建的文件内部为空
mkdir()
用于创建文件夹,注意,只能用于创建一级文件夹
File fire2=new File("D:\\code\\bbb");
System.out.println(fire2.mkdir());
mkdirs()
可以用于创建多级文件夹
File fire3=new File("D:\\code\\ccc\\ddd\\eee\\fff\\ggg");
System.out.println(fire3.mkdirs());
delete()
删除文件(只能删除文件或空文件夹,非空文件夹不能删除《主要为了防止D盘这类重要被删除》)
System.out.println(fire1.delete());
System.out.println(fire2.delete());
System.out.println(fire3.delete());//多级文件夹不属于空文件夹,不可以删除//false
System.out.println(file.delete());
经过测试多级文件夹不可以删除,所以它不属于空文件夹
deltte删除后的文件不会进入回收站
遍历文件夹
list
获取当前目录下所有"一级文件名称"到一个字符串数组中
File file4=new File("D:\\code");
String[] list = file4.list();
for (String name : list) {
System.out.println(name);
}
listFiles
获取当前目录下所有以及文件对象,放到字符串对象数组中
File[] files = file4.listFiles();
for (File fire : files) {
System.out.println(fire.getAbsoluteFile());
}
注意!以下对于listFiles
当主调是文件或路径不存在时,返回null
当主调是一个空文件夹时返回一个长度为0的数组
当主调是一个有内容的文件夹时将里面所有以及文件和文件夹的路径放进fire数组中返回
当主调是一个文件夹且里面有隐藏文件时,将里面所有以及文件和文件夹的路径放进fire数组中返回,包括隐藏文件
当主调是一个文件夹,但没有权限访问该文件夹时,返回null
递归:
递归是一种算法,在程序设计语言中广泛运用
方法调用自身的形式就称之为方法递归
方法递归的形式:
1.直接递归
方法自己调用自己
public static void test1(){
System.out.println("---test1---");
test1();
//StackOverflowError
//栈内存溢出
}
2.间接递归
另一个方法调用它
public static void test2(){
System.out.println("---test2---");
test3();
}
private static void test3() {
System.out.println("---test3---");
test2();
}
注意:如果不设定好方法递归的终止就会出现栈内存溢出的问题,以上两者都有