目录
LinkedHashSet : HashSet基础上又加了一条链表
Collection三种通用的遍历方式(迭代器遍历,增强for遍历,lambda遍历)
HashMap: 无序,不重复,无索引 ----若无特殊要求,默认使用HashMap 效率最高!!!
TreeMap: TreeMap和TreeSet底层原理一样,都是红黑树结构
集合体系结构分单列集合和双列集合
单列集合Collection
双列集合Map
创建集合的对象
泛型:限定集合中存储数据的类型
ArrayList<String> list = new ArrayList<String>(); JDK7
基本数据类型对应的包装类
byte => Byte
short => Short
char => Character
int => integer
long => Long
float => Float
double => Double
boolean => Boolean
扩展: Collections常用API
Collection:
是单列集合的祖宗(顶层)接口,它的功能是全部单列集合都可以继承使用的
所有方法被List和Set方法共享
List系列:添加的元素是有序的、可重复、有索引
ArrayList: 数组list系列
LinkedList: 链表list系列
Vector(已淘汰)
Set系列:添加的元素是无序,不重复,无索引
HashSet:
哈希表set系列
LinkedHasgSet
TreeSet: 树set系列
LinkedHashSet : HashSet基础上又加了一条链表
Collection方法:
public boolean add(E e) 把给定的对象添加到当前集合中
public void clear() 清空集合中所有的元素
public boolean remove(E e) 把给定的对象在当前集合中删除
public boolean contains(object obj) 判断当前集合中是否包含给定的对象
public boolean isEmpty() 判断当前集合是否为空
public int size() 返回集合中元素的个数/集合的长度
注意点:
Collection是一个接口,我们不能直接创建它的对象
所以,现在学习它的方法时,只能创建它实现类的对象
实现类:ArrayList
方法会有一个boolean类型的返回值,操作成功会返回true,操作失败会返回false
Collection三种通用的遍历方式(迭代器遍历,增强for遍历,lambda遍历)
迭代器遍历
迭代器在java中的类是Iterator,迭代器是集合专用的遍历方式
Collection集合获取迭代器
Iterator<E> iterator() 返回迭代器对象,默认指向当前集合的0索引
Iterator中的常用方法:
boolean hasNext() 判断当前位置是否有元素,有返回true,无返回false
E next() 获取当前位置的元素,并将迭代器对象移向下一个位置
细节注意点:
1.报错NOSuchElementException 没有这个元素异常点,当前指针指向无元素
2.迭代器遍历完毕,指针不会复位
3.循环中只能用一次next方法
4.迭代器遍历时,不能用集合的方法进行增加或删除
增强for遍历:
增强for的底层就是迭代器,为了简化迭代器的代码书写的
它是JDK5之后出现的,其内部原理就是一个Iterator迭代器
所有的单列集合和数组才能用增强for进行遍历
格式:
for(元素的数据类型 变量名:数组或者集合){
}
案列: for(String s:list){
System.out.println(s);
}
修改增强for中的变量,不会改变集合中的原本的数据。
lambda表达式遍历:
default void forEach(Consumer<? super T> action):
List集合
List集合的特点:
有序:存和取的元素顺序一致
有索引:可以通过索引操作元素
可重复:存储的元素可以重复
List:
ArrayList
LinkedList
Vector
List是Collection的一种,Collection的方法都被List继承了
void add(int index,E element) 在此集合中的指定位置插入指定的元素
E remove(int index) 删除指定索引处的元素,返回被删除的元素
E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
E get(int index) 返回指定索引处的元素
ArrayList成员方法: 增删改查
boolean add(E e) 添加元素,返回值表示是否添加成功
boolean remove(E e) 删除指定元素,返回值表示是否删除成功
E remove(int index) 删除指定索引的元素,返回被删除元素
E set(int index,E e) 修改指定索引下的元素,返回原来的元素
E get(int index) 获取指定索引的元素
int size() 集合的长度,也就是集合中元素的个数
//JDK8以上版本后面可不用再写String
ArrayList<String> list = new ArrayList<>(); //表示此集合只存储String类型
System.out.println(list);
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eeee");
//System.out.println(result);
System.out.println(list);
list.remove("aaa");
System.out.println(list);
list.remove(3);
System.out.println(list);
list.set(0, "abc"); //修改指定索引的元素,替换为新值
System.out.println(list);
String get = list.get(0);
System.out.println(get);
int s = list.size();
System.out.println(s);
//遍历
for(int i=0; i<list.size();i++) {
String ArrayList = list.get(i);
System.out.println(ArrayList);
}
番外扩展:
数据结构特点及作用:
栈:后进先出,先进后出
队列:先进先出,后进后出
数组:内存连续区域,查询快,增删慢
链表:元素是游离的,查询慢,首尾操作极快
set集合
Set系列集合:
无序:存储顺序不一致
不重复:可以去除重复
无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素
Set集合的实现类:
HashSet:无序,不重复,无索引
LinkedHashSet:有序,不重复,无索引
TreeSet:可排序,不重复,无索引
Set接口中的方法基本上与Collection的API一致
遍历:迭代器,增强for,Lambda表达式
HashSet底层原理:
HashSet集合底层采取哈希表存储数据
哈希表是一种对于增删改查数据性能都比较好的结构。
哈希表组成:
JDK8之前:数组+链表
JDK8开始:数组+链表+红黑树
哈希值:对象的整数表现形式
根据hashCode方法算出来的int类型的整数
该方法定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
一般情况下,会重写hashCode方法,利用对象内部的属性值计算哈希值
对象的哈希值特点:如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
如果已经重写hashCode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
在小部分情况下,不同的属性值或者不同的地址值计算出的哈希值也有可能一样。(哈希碰撞)有可能发生但概率不高
//重写hashCode方法
@Override
public int hashCode() {
return Objects.hash(name,age);
}
HashSet底层原理:
1.创建一个默认长度为16,默认加载因子0.75的数组,数组名table
HashSet<String> hm = new HashSet<>();
2.根据元素的哈希值与数组的长度计算出应存入的位置
int index = (数组长度-1) & 哈希值
3.判断当前位置是否为null,如果是null直接存入
4.如果位置不为null,表示有元素,则调用equals方法比较属性值
比较后一样:不存
比较后不一样:存入数组,形成链表
JDK8以前:新元素存入数组,老元素挂在新元素下面
JDK8以后:新元素直接挂在老元素下面
当链表长度超过8,而且数组长度大于等于64时,自动转换为红黑树
如果集合中存储的是自定义对象,必须要重写hashCode和equals方法
HashSet是利用什么机制保证数据的去重
1.HashCode方法
2.equals方法
LinkedHashSet底层原理: 有序,不重复,无索引
这里的有序指的是保证存储和取出的元素顺序一致
原理:底层数据结构依然是哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序
TreeSet特点:不重复,无索引,可排序
可排序:按照元素的默认规则(由小到大)排序
TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都比较好
TreeSet集合默认的规则: 对于数值类型:Integer,Double 默认按照从小到大的顺序进行排序
对于字符,字符串类型:按照字符在ASCII码表中的数字升序进行排序
两种比较方式: (如果两种方式都存在,默认使用第二种)
1.默认的排序规则/自然排序:(默认使用此,若不满足,再第二种)
Student对象实现Comparable接口,重写里面的抽象方法,再指定比较规则
2.比较器排序:
创建TreeSet对象时候,传递比较器Comparator指定规则
如果想要集合中的元素可重复: 用ArrayList集合,基于数组的(用的最多)
如果想要集合中的元素可重复,而且当前的增删操作明显多于查询: 用LinkedList集合,基于链表的
如果想对集合中的元素去重: 用HashSet集合,基于哈希表的(用的最多)
如果想对集合中的元素去重,而且保证存取顺序: 用LinkedHashSet集合,基于哈希表和双链表,效率低于HashSet
如果想对集合中的元素进行排序: 用TreeSet集合,基于红黑树,后续也可以用List集合实现排序。
Set<String> se = new HashSet<>();
se.add("aaa");
se.add("bbb");
se.add("ccc");
se.add("ddd");
System.out.println(se);
//迭代器遍历
System.out.println("-------迭代器遍历--------");
Iterator<String> itse = se.iterator();
while(itse.hasNext()) {
String s = itse.next();
System.out.print(s+" ");
}
//增强for遍历
System.out.println();
System.out.println("-----增强for遍历-------");
for(String s: se) {
System.out.print(s+" ");
}
//Lambda表达式遍历
System.out.println();
System.out.println("-----Lambda表达式遍历-------");
se.forEach((String s) -> {
System.out.print(s+" ");
});
System.out.println();
System.out.println("-----Lambda表达式简易版遍历-------");
se.forEach(s -> System.out.print(s+" "));
//哈希值部分
System.out.println();
System.out.println("哈希值部分");
Student s1 = new Student();
Student s2 = new Student();
int hashs1 = s1.hashCode();
int hashs2 = s2.hashCode();
//没有重写hashCode时。不同对象计算出的哈希值不同
//重写hashCode方法后,属性值相同的对象计算出的哈希值相同。
System.out.println("s1的哈希值:"+hashs1);
System.out.println("s2的哈希值:"+hashs2);
//HashSet去重
System.out.println();
System.out.println("-------HashSet去重--------");
Student ss1 = new Student("月月",16);
Student ss2 = new Student("芊芊",17);
Student ss3 = new Student("芊芊",17);
Student ss4 = new Student("恋恋",19);
//创建集合存储对象
HashSet<Student> sh = new HashSet<>();
//添加元素
System.out.println(sh.add(ss1));
System.out.println(sh.add(ss2));
System.out.println(sh.add(ss3)); //false 重写HashCode方法后重复对象无法添加
System.out.println(sh.add(ss4));
System.out.println(sh);
System.out.println();
System.out.println("-------LinkedHashSet--------");
LinkedHashSet<Student> lsh = new LinkedHashSet<>();
//添加元素
System.out.println(lsh.add(ss1));
System.out.println(lsh.add(ss2));
System.out.println(lsh.add(ss3));
System.out.println(lsh.add(ss4));
System.out.println(lsh);
System.out.println();
System.out.println("-------TreeSet--------");
TreeSet<Integer> in = new TreeSet<>();
in.add(5);
in.add(4);
in.add(3);
in.add(2);
in.add(1);
System.out.println(in); //自动排序 从小到大
//迭代器遍历
Iterator<Integer> ini = in.iterator();
while(ini.hasNext()) {
int i = ini.next();
System.out.print(i+" ");
}
System.out.println("\n");
System.out.println("----用TreeSet进行学生对象排序-----");
System.out.println("---- 默认的排序规则/自然排序-----");
Student t1 = new Student("zhangsan",16);
Student t2 = new Student("lisi",17);
Student t3 = new Student("wangwu",18);
TreeSet<Student> ts = new TreeSet<>();
ts.add(t1);
ts.add(t2);
ts.add(t3);
System.out.println(ts); //如诺报错,是因为未指定排序规则,需要手动对Student对象实现Comparable接口,并重写抽象方法
System.out.println("---- 比较器排序----");
//o1表示当前要添加的元素
//o2表示已经在红黑树存在的元素
//返回值与Comparable一致
TreeSet<String> t = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1,String o2) {
//return 0;
//按照长度排序
int i = o1.length() - o2.length();
//如果一样长按照首字母排序
i =i == 0 ? o1.compareTo(o2) : i;
return i;
}
});
t.add("aa");
t.add("aab");
t.add("cba");
t.add("bca");
t.add("aac");
t.add("cac");
t.add("cab");
System.out.println(t);
双列集合:Map
HashMap: 无序,不重复,无索引 ----若无特殊要求,默认使用HashMap 效率最高!!!
LinkedHashMap :有序,不重复,无索引 (由键决定)
有序指的是保证存储和取出的元素顺序一致
原理:底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序
Hashtable:
Properties
TreeMap: TreeMap和TreeSet底层原理一样,都是红黑树结构
由键决定特性: 不重复,无索引,可排序
可排序:对键进行排序
注意:默认按照键的从小到大的顺序排序,也可以自己规定键的排序规则
两种排序规则:
1.实现Comparable接口,指定比较规则
2.创建集合时传递Comparator比较器对象,指定比较规则
HashMap的特点: HashMap是Map里面的一个实现类
没有额外需要学习的特有方法,直接使用Map里面的方法就可以了
特点都是由键决定的: 无序,不重复,无索引
HashMap跟HashSet底层原理是一模一样的,都是哈希表结构。
依赖hashCode和equals方法保证键的唯一
如果键存储的是自定义对象,需要重写hashCode和equals方法
如果值存储自定义对象,不需要重写hashCode和equals方法
双列集合一次需要存一对数据,分别为键和值
左边一列为键 右边一列为值 键和值一一对应 键+值称为 键值对 或者 键值对对象(Entry对象)
键是唯一的不能重复
值不唯一可以是重复的
Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的
V put(K key,V value) 添加元素(覆盖元素)
添加数据的时候,如果键不存在,直接把键值对对象添加到map集合当中
添加数据的时候,如果键是存在的,会把原有的键值对对象覆盖,会把被覆盖的值进行返回
V remove(Object key) 根据键删除键值对元素
void clear() 移除所有的键值对元素(清空)
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数
Map遍历
Map的遍历方式一:键找值!!!
步骤:
1.获取所有的键,把这些键放到一个单列集合中
Set<String> keys = map.keySet();
2.遍历集合,得到每一个键
迭代器、增强for、Lambda.
3.利用Map集合中的键获取对应的值----get()
String value = map.get(key);
Map的遍历方式二:键值对!!!
getKey()获取键
getValue()获取值
Map的遍历方式三之Lambda表达式:
default void forEach(BiConsumer<? super K, ? super V> action) 结合lambda遍历Map集合
例子:
map.forEach((String key, String value) ->{
System.out.print(key+"="+value+" ");
});
//创建双列集合
Map<String,String> map = new HashMap<>();
map.put("郭靖", "黄蓉");
map.put("长安", "故里");
map.put("月下", "独酌");
map.put("张三丰", "峨眉师太");
String re = map.put("郭靖", "蓉蓉");
System.out.println(map);
System.out.println(re);
/* //清空
map.clear();
System.out.println(map);
*/
boolean ck = map.containsKey("张三丰");
boolean cv = map.containsValue("蓉蓉");
boolean cv1 = map.containsValue("蓉儿");
System.out.println(ck);
System.out.println(cv);
System.out.println(cv1);
boolean rep = map.isEmpty();
System.out.println(rep);
int sz = map.size();
System.out.println(sz);
//遍历方式一-----键找值!!!
//获取所有键放到一个集合里
Set<String> keys = map.keySet();
//遍历
for(String key:keys) {
System.out.print(key+": ");
String value = map.get(key);
System.out.println(key+"="+value);
}
//遍历方式二-----键值对!!!
System.out.println("\n");
//通过一个方法获取所有的键值对对象,返回一个Set集合
Set<Map.Entry<String, String>> entries = map.entrySet();
//用entries集合遍历得到每一个键值对对象
for(Map.Entry<String, String> entry: entries) {
String key = entry.getKey();//键
String value = entry.getValue();//值
System.out.print(key+"="+value+" ");
}
//遍历方式二-----Lambda表达式!!!
System.out.println("\n");
System.out.println("--------Lambda表达式---------\n");
map.forEach((String key, String value) ->{
System.out.print(key+"="+value+" ");
});
System.out.println("\n");
System.out.print("---------------------------------------------------------------\n");
System.out.print("创建一个HashMap集合,键是学生对象(Student),值是籍贯(String)\n");
System.out.print("存储三个键值对元素,并遍历\n");
System.out.println("要求:同姓名同年龄认为是同一个学生\n");
//创建集合
HashMap<Student,String> st = new HashMap<>();
//创建学生对象
Student s1 = new Student("zhangsan",17);
Student s2 = new Student("lisi",18);
Student s3 = new Student("wangwu",19);
Student s4 = new Student("qianliu",20);
Student s5 = new Student("qianliu",20);
//添加
st.put(s1, "云南");
st.put(s2, "曲靖");
st.put(s3, "宣威");
st.put(s4, "玉溪");
st.put(s5, "红河");
//遍历
//找出所有键放入集合
Set<Student> stukeys = st.keySet();
for(Student stukey : stukeys) {
String value = st.get(stukey);
System.out.println(stukey+"="+value+" ");
}
System.out.println("\n");
System.out.print("---------------------------------------------------------------\n");
System.out.print("某个班级80个学生,现在需要组成秋游活动\n");
System.out.print("班长提供了四个景点依次是{A,B,C,D}\n");
System.out.println("每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多\n");
//定义数组,存储景点
String[] arr = {"A","B","C","D"};
//随机数模拟80位同学的投票
Random ran = new Random();
//创建集合存储投票结果
ArrayList<String> list = new ArrayList<>();
//随机
for(int i=0;i<80;i++) {
int index = ran.nextInt(arr.length);//获取索引
list.add(arr[index]);//添加进集合
}
//如果统计的东西较多,是不方便使用计数器思想的
//可以定义Map集合,利用集合进行统计
//键表示统计的东西,值表示票数
HashMap<String,Integer> hm = new HashMap<>();
for(String name : list) {
//判断当前景点在Map集合中是否存在
if(hm.containsKey(name)) {
//存在
//先获取当前景点已被投票的次数
int count = hm.get(name); //获取值
count++;//值自增
//把新次数再次添加进集合中,覆盖原有的
hm.put(name, count);
}else {
//不存在
hm.put(name, 1);
}
}
System.out.println(hm);
//求最大值
int max = 0;
Set<Map.Entry<String, Integer>> stentries = hm.entrySet();
for(Map.Entry<String, Integer> entry : stentries) {
int count = entry.getValue();
if(count > max) {
max = count;
}
}
System.out.println("最高票数"+max);
//判断重复票数的景点,即俩景点投票数相同
for(Map.Entry<String, Integer> entry : stentries) {
int count = entry.getValue();
if(count == max) {
System.out.println("票数最高的景点是"+entry.getKey());
}
}
System.out.println("\n");
System.out.print("------------TreeMap----------------\n");
TreeMap<Student,String> tm = new TreeMap<>();
tm.put(s1, "云南");
tm.put(s2, "关东");
tm.put(s3, "上海");
tm.put(s4, "玉溪");
System.out.println(tm+" ");
System.out.println("\n");
System.out.print("---------------------------------------------------------------\n");
System.out.print("统计字符串aababcabcdabcde中单个字符出现的次数\n");
String s = "aababcabcdabcde";
//创建集合
TreeMap<Character,Integer> tc = new TreeMap<>();
//遍历
for(int i=0;i<s.length();i++) {
char c = s.charAt(i);
System.out.print(c+" ");
//拿着c到集合中判断是否存在,如果存在就+1,不存在就添加
if(tc.containsKey(c)) {
int count = tc.get(c);//获取值
count++;//值++
tc.put(c, count);//重新添加
}else {
tc.put(c, 1);
}
}
System.out.println();
System.out.println(tc);
//遍历集合,并按指定的格式进行拼接-----a(5)b(4)c(3)d(2)e(1)
StringBuilder sb = new StringBuilder();
//通过一个方法获取所有的键值对对象,返回一个Set集合
Set<Map.Entry<Character, Integer>> tcentries = tc.entrySet();
//增强for遍历并用StringBuilder进行字符拼接
for(Map.Entry<Character, Integer> entry : tcentries) {
char key = entry.getKey();
int value = entry.getValue();
sb.append(key).append("(").append(value).append(")");
}
System.out.println(sb);
System.out.println("\n");
System.out.print("-----------------------集合的嵌套----------------------------------\n");
/*
* 江苏省=南京市,扬州市,苏州市,无锡市,常州市
* 湖北省=武汉市,孝感市,十堰市,宜昌市,鄂州市
* 河北省=石家庄市,唐山市,邢台市,保定市,张家口市
*
* */
//创建Map集合
HashMap<String,ArrayList<String>> province = new HashMap<>();
//创建单列集合存储市区
ArrayList<String> city1 = new ArrayList<>();
city1.add("南京市");
city1.add("扬州市");
city1.add("苏州市");
city1.add("无锡市");
city1.add("常州市");
ArrayList<String> city2 = new ArrayList<>();
city2.add("武汉市");
city2.add("孝感市");
city2.add("十堰市");
city2.add("宜昌市");
city2.add("鄂州市");
ArrayList<String> city3 = new ArrayList<>();
city3.add("石家庄市");
city3.add("唐山市");
city3.add("邢台市");
city3.add("保定市");
city3.add("张家口市");
//添加元素
province.put("江苏省", city1);
province.put("湖北省", city2);
province.put("河北省", city3);
System.out.println(province+"\n");
//Entry方法获取键值对对象
Set<Map.Entry<String, ArrayList<String>>> pentries = province.entrySet();
//增强for遍历
for(Map.Entry<String, ArrayList<String>> entry : pentries) {
String key = entry.getKey();
ArrayList<String> value = entry.getValue();
StringJoiner sj = new StringJoiner(",","",""); //指定间隔,开始,结束标志
for(String city : value) { //增强for遍历值-----city
sj.add(city);
}
System.out.println(key+"="+sj);
}
随机点名案列:
//随机点名
System.out.println("-----------------1.0------------------------------------------");
//创建集合存储数据
ArrayList<String> list = new ArrayList<>();
//添加数据
Collections.addAll(list,"范闲","凡间","张三","李四","王五","前六","李白",
"杜甫","王维","张道陵","张子凡","李星云","陆令萱","不良帅","姬如雪","杜子腾","王权富贵");
System.out.println(list.size());
Random ran = new Random();
int index = ran.nextInt(list.size());
String name = list.get(index);
System.out.println(name);
System.out.println("-----------------2.0(男70女30概率)------------------------------------------");
//概率集合
ArrayList<Integer> list1 = new ArrayList<>();
Collections.addAll(list1, 1,1,1,1,1,1,1); // 70%概率
Collections.addAll(list1, 0,0,0); // 30%概率
//打乱数据
Collections.shuffle(list1);
//从集合中随机0和1
Random ran1 = new Random();
int index1 = ran.nextInt(list1.size()); //获取随机索引
int number = list1.get(index1); //用随机索引获取集合中的数据
System.out.println(number);
//创建男女两个集合用来存放名字
ArrayList<String> boylist1 = new ArrayList<>();
ArrayList<String> girllist1 = new ArrayList<>();
//添加元素
Collections.addAll(boylist1, "范闲","凡间","张三","李四","王五","前六","李白",
"杜甫","王维","张道陵","张子凡","李星云","不良帅","杜子腾","王权富贵");
Collections.addAll(girllist1,"陆令萱","姬如雪","小龙女","梅超风","大师姐","小师妹","钟莉","月下独酌","南宫月月");
//判断number是1或0,1代表70概率,0代表30概率
if(number == 1) {
int boyindex = ran1.nextInt(boylist1.size());
String name1 = boylist1.get(boyindex);
System.out.println(name1);
}else{
int girlindex = ran1.nextInt(girllist1.size());
String name1 = girllist1.get(girlindex);
System.out.println(name1);
}
System.out.println("-----------------3.0(点到的不会再点,点完重新开启第二轮)------------------------------------------");
ArrayList<String> list3 = new ArrayList<>();
Collections.addAll(list3,"范闲","凡间","张三","李四","王五","前六","李白",
"杜甫","王维","张道陵","张子凡","李星云","陆令萱","不良帅","姬如雪","杜子腾","王权富贵");
//创建临时集合用来存放已经点过名的名字
ArrayList<String> list3_1 = new ArrayList<>();
//外循环表示轮数
for(int i=1;i<=10;i++) {
System.out.println("=======第"+i+"轮点名=========");
int count = list3.size();
Random r = new Random();
for(int j=0;j<count;j++) {
int index3 = r.nextInt(list3.size());
String name3 = list3.remove(index3);
list3_1.add(name3);
System.out.println(name3);
}
//此时表示一轮点名结束 list3空了 list3_1满了
list3.addAll(list3_1);
list3_1.clear();
}
public class Student implements Comparable<Student>{
private String name;
private int age;
//空参构造
public Student() {
}
//带参
public Student(String name,int age) {
this.name = name;
this.age = age;
}
//getter and setter
public String getName(String name) {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge() {
this.age =age;
}
//重写hashCode方法
@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 && Objects.equals(name,student.name);
}
@Override
public int hashCode() {
return Objects.hash(name,age);
}
public String toString() {
return "Student{name="+name+",age="+age+"}";
}
//默认的排序规则/自然排序
@Override
public int compareTo(Student o) {
// TODO 自动生成的方法存根
//return 0;
//指定排序的规则
//只看年龄,按照年龄升序进行排序
return this.getAge() - o.getAge();
/*
* this表示当前要添加的元素
* o表示已经在红黑树存在的元素
* 返回值:
* 负数:认为要添加的元素是小的,存左边
* 正数:认为要添加的元素是大的,存右边
* 0:认为要添加的元素已经存在,舍弃
* */
}
扩展:可变参数:
可变参数本质上就是一个数组
作用:在形参中接受多个数据
可变参数:方法形参的个数是可以发生改变的
格式: 属性类型...名字
例子: int...args args在方法创建中相当于一个数组
细节: 在方法的形参中最多只能写一个可变参数
在方法当中,如果除了可变参数以外,还有其它参数,那么可变参数要写在最后