> 文章列表 > 185-二35

185-二35

185-二35

Java185-二35

  • 单列集合顶层接口collection
  • 迭代器
  • 增强for
  • lambda表达式
  • list特有方法
  • 遍历
  • 数据结构
  • 数组
  • Linkedlist集合
  • 泛型类,泛型方法,泛型结构
  • 泛型方法
  • 泛型的通配符
    • 泛型总结
  • 数据结构
    • 数据结构(二叉树)前序遍历
    • 数据结构(二叉树)中序遍历
    • 数据结构(二叉树)后序遍历
    • 平衡二叉树:任意节点左右子树高度差不超过1
  • 红黑树
  • 集合进阶
  • Map集合
  • MAP集合遍历
  • 第二种遍历
  • 第三种lambda表达式
  • HashMap
  • LinkedHashMap
  • TreeMap
  • 可变参数
  • 集合工具类Collections
  • 带有概率的随机点名
    • shift+f6快捷更改
  • 不可变集合

单列集合顶层接口collection

185-二35

迭代器

185-二35

//1.创建集合并添加元素
Collection<String> coll = new ArrayList<>();
col1.add("aaa");
col1.add("bbb");
col1.add("ccc");
col1.add("ddd");|
//2.获取迭代器对象
//迭代器就好比是一个箭头,默认指向集合的0索引处
Iterator<String> it = coll.iterator();
//3.利用循环不断的去获取集合中的每一个元素
while(it.hasNext()){
//4.next方法的两件事情:获取元素并移动指针
String str = it.next();
System.out.println(str);
}

迭代器的细节注意点:
1.报错NoSuchElementException
2.迭代器遍历完毕,指针不会复位
3.循环中只能用一次next方法
4.迭代器遍历时,不能用集合的方法进行增加或者删除

增强for

lambda表达式

//1.创建集合并添加元素
Collection<String> coll = new ArrayList<>();
coll.add("zhangsan");
coll.add("lisi");
co11.add("wangwu");
//2.利用匿名内部类的形式
/底层原理:
/其实也会自己遍历集合,依次得到每一个元素
//把得到的每一个元素,传递给下面的accept方法
//s依次表示集合中的每一个数据
/* col1.forEach(new Consumer<String>(){
@Override
public void accept(String s){
System.out.println(s);
3
});*/
//lambda表达式
coll.forEach(s -> System.out.println(s));

list特有方法

185-二35

遍历

//1.迭代器
/*Iterator<String> it = list.iterator();
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}*/
//2.增强for
//下面的变量s,其实就是一个第三方的变量而已。
/在循环的过程中,依次表示集合中的每一个元素
/* for (String s : list) {
System.out.println(s);
}*/
//3.Lambda表达式
//forEach方法的底层其实就是一个循环遍历,依次得到集合中的每一个元素
//并把每一个元素传递给下面的accept方法
//accept方法的形参s,依次表示集合中的每一个元素
//list.forEach(s->System.out.println(s) );
//4.普通for循环
//size方法跟get方法还有循环结合的方式,利用索引获取到集合中的每一个元素
/*for (int i = 0; i < list.size(); i++) {
//i:依次表示集合中的每一个索引
String s = list.get(i);
System.out.println(s);
}*///5.列表迭代器
//获取一个列表迭代器的对象,里面的指针默认也是指向e索引的
//额外添加了一个方法:在遍历的过程中,可以添加元素
ListIterator<String> it = list.listIterator();
while(it.hasNext()){
String str = it.next();
if("bbb".equals(str)){
//qqq
it.add("qqq");System.out.println(list);
}
}

数据结构

185-二35

数组

查询快,增删慢

Linkedlist集合

185-二35

泛型类,泛型方法,泛型结构

//没有泛型的时候,集合如何存储数据
//1.创建集合的对象
ArrayList list = new ArrayList();
//2.添加数据
list.add(123);
list.add("aaa");|
list.add(new Student( name: "zhangsan", age: 123));
//3.遍历集合获取里面的每一个元素
Iterator it = list.iterator();
while(it.hasNext()){
String str = (String) it.next();
/多态的弊端是不能访问子类的特有功能
//obj.length();
str.length();
System.out.println(str);
}

泛型的细节
泛型中不能写基本数据类型
指定泛型的具体类型后,传递数据时,可以传入该类类型或者其子类类型
如果不写泛型,类型默认是Object
185-二35

public class MyArrayList<E> {
0bject[] obj = new Object[10];
int size;
/*
E:表示是不确定的类型。该类型在类名后面已经定义过了。
e:形参的名字,变量名
/
public boolean add(E e){
obj[size] = e;
size++;
return true;
}
public E get(int index) { return (E)obj[index]; }
@Override
public String toString() {
return Arrays.tostring(obj);
}
}

泛型方法

方法中形参类型不确定时

方案①:使用类名后面定义的泛型 所有方法都能用

方案②:在方法申明上定义自己的泛型 只有本方法能用
185-二35

泛型的通配符

此时,泛型里面写的是什么类型,那么只能传递什么类型的数据。
弊端:
A
利用泛型方法有一个小弊端,此时他可以接受任意的数据类型
Ye Fu Zi
Student
希望:本方法虽然不确定类型,但是以后我希望只能传递Ye Fu Zi
此时我们就可以使用泛型的通配符:
?也表示不确定的类型
他可以进行类型的限定
?extends E:表示可以传递E或者E所有的子类类型
?super E:表示可以传递E或者E所有的父类类型
应用场景:
1.如果我们在定义类、方法、接口的时候,如果类型不确定,就可以定义泛型类、泛型方法、泛型接口。
2.如果类型不确定,但是能知道以后只能传递某个继承体系中的,就可以泛型的通配符
泛型的通配符:
关键点:可以限定类型的范围。

public static void method(ArrayList<? super Fu> list) {
}

泛型总结

1.什么是泛型?
JDK5引入的特性,可以在编译阶段约束操作的数据类型,并进行检查
2.泛型的好处?
统一数据类型
把运行时期的问题提前到了编译期间,避免了强制
类型转换可能出现的异常,因为在编译阶段类型就能确定下来。
3.泛型的细节?
泛型中不能写基本数据类型
指定泛型的具体类型后,传递数据时,可以传入该类型和他的子类类型
如果不写泛型,类型默认是object
4.哪里定义泛型?
泛型类:在类名后面定义泛型,创建该类对象的时候,确定类型
泛型方法:在修饰符后面定义方法,调用该方法的时候,确定类型
泛型接口:在接口名后面定义泛型,实现类确定类型,实现类延续泛型
5.泛型的继承和通配符
泛型不具备继承性,但是数据具备继承性
泛型的通配符:?
? extend E
? super E
6.使用场景
定义类、方法、接口的时候,如果类型不确定,就可以定义泛型
如果类型不确定,但是能知道是哪个继承体系中的,可以使用泛型的通配符

数据结构

185-二35
185-二35

数据结构(二叉树)前序遍历

从根结点开始,然后按照当前结点,左子结点,右子结点的顺序遍历

数据结构(二叉树)中序遍历

从最左边的子节点开始,然后按照左子结点,当前结点,右子结点的顺序遍历

数据结构(二叉树)后序遍历

从最左边的子节点开始,然后按照左子结点,右子结点,当前结点的顺序遍历

平衡二叉树:任意节点左右子树高度差不超过1

185-二35

红黑树

185-二35

集合进阶

185-二35

Map集合

185-二35

//1.创建Map集合的对象
Map<String, String> m = new HashMap<>();
//2.添加元素
//put方法的细节:
/∥添加/覆盖
//在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中,方法返回nu11
//在添加数据的时候,如果键是存在的,那么会把原有的键值对对象覆盖,会把被覆盖的值进行返回。
String value1=m.put("郭靖""黄蓉";
System.out.println(value1);
m.put(“韦小宝“,“沐剑屏“);
m.put(“尹志平“,“小龙女“);
String value2=m.put("韦小宝""双儿");
System.out.println(value2);
//3.打印集合
System.out.println(m);//???

185-二35

MAP集合遍历

//三个课堂练习:
//
//练习一:
利用键找值的方式遍历map集合,要求:装着键的单列集合使用增强for的形式进行遍历
利用键找值的方式遍历map集合,要求:装着键的单列集合使用迭代器的形式进行遍历
//练习二:
//练习三:
利用键找值的方式遍历map集合,要求:装着键的单列集合使用1ambda表达式的形式进行遍历
1
//1.创建Map集合的对象
Map<String,String> map = new HashMap<>();
//2.添加元素
map.put("尹志平""小龙女";
map.put("郭靖",“穆念慈");
map.put("欧阳克""黄蓉");
//3.通过键找值
//3.1获取所有的键,把这些键放到一个单列集合当中
Set<String> keys = map.keySet();
//3.2遍历单列集合,得到每一个键
for(String key :keys){
//System.out.println(key);
//3.3利用map集合中的键获取对应的值 get
String value = map.get(key);
System.out.println(key + " =" + value);
3

第二种遍历

/1.创建Map集合的对象
Map<String,String> map = new HashMap<>();
//2.添加元素
//键:人物的外号/值:人物的名字
map.put("标枪选手",“马超");
map.put("人物挂件""明世隐");
map.put("御龙骑士",“尹志平");
//3.Map集合的第二种遍历方式
/通过键值对对象进行遍历
//3.1通过一个方法获取所有的键值对对象,返回一个Set集合
Set<Map.Entry<String, String>> entries = map.entrySet();
//3.2遍历entries这个集合,去得到里面的每一个键值对对象
for (Map.Entry<String, String> entry : entries) {//entry --->
}
“人物挂件”,”明世隐”
//3.3利用entry调用get方法获取键和值
String key = entry.getkey();
String value = entry.getValue();
System.out.println(key + "=" + value);
}

第三种lambda表达式

185-二35

//3.利用lambda表达式进行遍历/底层:
//forEach其实就是利用第二种方式进行遍历,依次得到每一个键和值
//再调用accept方法
map.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String key, String value) {
System.out.println(key + "=" + value);
3
});
System.out.println(".
");
map.forEach((String key, String value)->{
System.out.println(key + "=" + value);
3
)System.out.println(".
")I
map.forEach((key, value)-> System.out.println(key + "=" + value));

HashMap

HashMap的特点
①HashMap是Map里面的一个实现类。
②没有额外需要学习的特有方法,直接使用Map里面的方法就可以了。
③特点都是由键决定的:无序、不重复、无索引
④ HashMap跟HashSet底层原理是一模一样的,都是哈希表结构

LinkedHashMap

185-二35

TreeMap

TreeMap跟TreeSet底层原理一样,都是红黑树结构的。
由键决定特性:不重复、无索引、可排序
可排序:对键进行排序。
注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则
代码书写两种排序规则
·实现Comparable接口,指定比较规则。
创建集合时传递Comparator比较器对象,
指定比较规则。

@0verride
public int compareTo(Student o) {
//按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名年龄视为同一个人。
//this:表示当前要添加的元素
//o:表示已经在红黑树中存在的元素
//返回值:
//负数:表示当前要添加的元素是小的,存左边
//正数:表示当前要添加的元素是大的,存右边
//0:表示当前要添加的元素已经存在,舍弃
int i = this.getAge() - o.getAge();
i = i == e? this.getName().compareTo(o.getName()) : i;
return i;|
}
}
/*需求:
字符串“aababcabcdabcde”
请统计字符串中每一个字符出现的次数,并按照以下格式输出
输出结果:
a (5) b (4) c (3) d (2) e (1)
新的统计思想:利用map集合进行统计
如果题目中没有要求对结果进行排序,默认使用HashMap
如果题目中要求对结果进行排序,请使用TreeMap
键:表示要统计的内容
值:表示次数
*///1.定义字符串
String s = "aababcabcdabcde";
//2.创建集合
TreeMap<Character,Integer> tm = new TreeMap<>();
//3.遍历字符串得到里面的每一个字符
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
//拿着c到集合中判断是否存在
/存在,表示当前字符又出现了一次
//不存在,表示当前字符是第一次出现
if(tm.containsKey(c)){
//存在
//先把已经出现的次数拿出来
int count = tm.get(c);
//当前字符又出现了一次
count++;
//把自增之后的结果再添加到集合当中
tm.put(c,count);
}else{/不存在
tm.put(c,1);
}
}
//4.遍历集合,并按照指定的格式进行拼接
// a (5) b (4) c (3) d (2) e (1)
StringBuilder sb = new StringBuilder();
tm.forEach(new BiConsumer<Character,Integer>(){
@Override
public void accept(Character key, Integer value) {
sb.append(key).append("(").append(value).append(")");
}
});
System.out.println(sb);

可变参数

JDK5
可变参数
方法形参的个数是可以发生变化的,e123...
格式:属性类型...名字
int...args

可变参数的小细节:
1.在方法的形参中最多只能写一个可变参数
可变参数,理解为一个大胖子,有多少吃多少
2.在方法的形参当中,如果出了可变参数以外,还有其他的形参,那么可变参数要写在最后

集合工具类Collections

185-二35

带有概率的随机点名

//1.创建集合
ArrayList<Integer> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list, ...elements: 1,1,1,1,1,1,1);
Collections.addAll(list, ...elements: 0,0,0);//3.打乱集合中的数据
Collections.shuffle(list);
//4.从1ist集合中随机抽取e或者1
Random r = new Random();
int index = r.nextInt(list.size());
int number = list.get(index);
System.out.println(number);
//5.创建两个集合分别存储男生和女生的名字
ArrayList<String> boyList = new ArrayList<>();
ArrayList<String> girlList = new ArrayList<>();
Collections.addALl(boyList,….elements:"范闲",“范建","范统",“杜子腾""宋合泛""侯笼藤""朱益群""朱穆朗玛峰")Collections.addALL(girlList,…elements:"杜琦燕","袁明媛","李猜","田蜜蜜");
//6.判断此时是从boyList里面抽取还是从girlList里面抽取
if(number == 1){
//boyList
int boyIndex = r.nextInt(boyList.size());
String name = boyList.get(boyIndex);
System.out.println(name);
}else{
//girlList
int girlIndex = r.nextInt(girlList.size());
String name = girlList.get(girlIndex);
System.out.println(name);
}

shift+f6快捷更改

不可变集合

185-二35
创建Map的不可变集合
细节1:
键是不能重复的
细节2:
Map里面的of方法,参数是有上限的,最多只能传递20个参数,10个键值对

//1.创建一个普通的Map集合
HashMap<String, String> hm = new HashMap<>();
hm.put("张三",“南京");
hm.put(“李四",“北京");
hm.put("王五""上海");
hm.put("赵六""北京");
hm.put(“孙七“,“深圳“);
hm.put("周八""杭州");
hm.put("吴九""宁波");
hm.put("郑十""苏州");
hm.put(“刘一",“无锡“);
hm.put(“陈二",“嘉兴“);
hm.put("aaa","111");
//2.利用上面的数据来获取一个不可变的集合
//获取到所有的键值对对象(Entry对象)
Set<Map.Entry<String, String>> entries = hm.entrySet();
//把entries变成一个数组
Map.Entry[] arr =new Map.Entry[20];|
//toArray方法在底层会比较集合的长度跟数组的长度两者的大小
//如果集合的长度>数组的长度:数据在数组中放不下,此时会根据实际数据的个数,重新创建数组
//如果集合的长度<=数组的长度:数据在数组中放的下,此时不会创建新的数组,而是直接用