集合完整版 原文档加微信 1875954969 ,原文档详细,格式阅读舒服,都是辛苦总结,需付费
- 复习数组的知识
一个普通类型的数组和一个引用类型的数组在内存上分配单元方法是不一样的注意区分。
Student[] stu = new Student[5];
stu[0] = new Student(“zhang”, 23);
由于初始化对象数组的时候,下标对应的空间存放的是引用,所以也可以
1 Student stu2 = new Student(“liu”, 22);
2 stu[1] = stu2;
异常现象一 :
Null是不可以调用方法的。
但是使用this调用放到Student类中,即使为空也会返回null
如:main()中
Student中:
- 数组和集合的区别,以及为什么要引入集合
ArrayList 底层使用的是arraycopy方法 实现的自动扩充长度,注意和Arrays.copyOf()区分 , 还有 Arrays.toString() 遍历数组
Java数组扩容的原理
1)Java数组对象的大小是固定不变的,数组对象是不可扩容的。
2)利用数组复制方法可以变通的实现数组扩容。
3)System.arraycopy()可以复制数组。
4)Arrays.copyOf()可以简便的创建数组副本。
5)创建数组副本的同时将数组长度增加就变通的实现了数组的扩容。
- 集合关系分布图
- Collection
使用collection作为上转型对象,遍历的时候得先把集合转换成数组才能实现功能
Object是所有类的父类,不管是integer类还是double类,还是student类型,使用上转型对象接收,没有任何问题。
遍历的时候也可以:
remove() 如果有重复的元素的话,只会删除第一个
cllection实现ArrayList时需要掌握的方法
由remove和contains的参数类型可知,在使用这两种方法操作对象时,会调用equals方法,但是没弄出来。。报的类型转换错误《已解决》
异常现象2:
已解决:使用对象类型的话就只使用对象类型,不要出现其他普通类型
或者:直接重写人家的equals();
- List
注意不要越界
特有方法,简单来记就是按照索引增删改查
异常现象5: 越界
异常现象6: 在遍历的时候不能通过集合对集合进行修改,会报修改异常
在 iterator中 , 可以用it.move进行删除 (iterator只有hasnext,next,remove这三种方法)
或者 使用 iterator的子类Listiterator来遍历 (看后面还有对三个遍历方法的比较,普通for循环按照索引排列,可以进行删除,但是在有重复类对象的时候要i--,增强for循环不可以(因为不可以用集合删除集合里的元素),iterator用it.remove()删除,如果用list操作同样不可以)
总之,不可以使用集合操作删除集合里面的数据(普通for循环除外,特别对待,底层是数组)
注意构造方法 : ListIterator it = list.listIterator(list.size()); //有一个index值
下面是可以逆序遍历previous()的一些方法
这里在遍历的时候还有一个易错点:尽量不要用it.next()
- 对于Vector,由于不常用了,记住下面这个就行了
- List集合的选择
- Arraylist本来是不去重复的,但是使用congtains()可以使集合实现去除重复数据
这段代码中有三点需要注意的地方:
1 静态方法
2转成字符串
3返回值和参数不要弄混
升级一下,如果是添加Student类对象的话,那么重写toString()和equals()即可。
- LinkedList
特有方法简单来记就是,增删两查
Get(int index) 和list里的方法用起来一样
由于linkedlist的特殊方法addFirst(),addLast() 和 removeFirst(),removeLast()所以linkedlist能够轻松模拟出 栈和队列 的数据结构
易错点: 老是记不清,这以后一定得记住
Public viod setName(String name){
This.name = name;
}
Public String getName(){
Return name;
}
已上集合可重复,按顺序存取
- 泛型(模板, 有类,有方法,有接口)
只有给出了确定的数据类型,这才是一个确定的类
如果不给出类型,默认传入的类型就是object类。
模板如下 :
也可以写 ToString() 方法,从而使用syso(t)显示,两种toString ()写法
泛型类
泛型方法
泛型接口
通配符<? Extends E>
没啥用,只要有继承关系就行了。
加强for循环,快速遍历数组或者集合 ————fore alt+/即可
就一句话: 使用变量I 表示数组(或集合)里的所有元素
增强for循环和普通for循环以及iterator遍历的区别
除了普通for循环,不能使用list直接操作集合,对应都有各自的方法
可变参数
- 数组合集合之间的转换
集合里面只能存放引用类型的数据
此处用char不行,没法转换成character,没法放进list集合中
- 嵌套集合
把集合当成一个对象就行了,遍历的时候嵌套遍历即可
List结束
- hashSet
当使用hashset 操作对象类型的数据时,去掉重复的数据,要重写hashcode()和equals()
操作普通数据类型的时候,则不需要写 hash()和equals(),在包装类中已经重写好了这两个方法。
集合框架练习1
1-20之间随机10个数
集合框架练习2:
字符串转换成字符的函数 : tochararray();
集合练习3:
根据hashset的去除重复的特性
Ctrl + 1 可以根据方法名字和参数直接创建一个静态方法
- linkedhashset
set集合中惟一一个,可以去重复,又可以按照 输入 顺序存储的集合
是hashset的子类
- treeset
放入 integer型数据 ,看一下结果就行
自定义对象类:
自然排序:(打开api看integer,它继承了compareable()接口,这就是为啥他能自动排序的原因)实现compareable接口,重写compareto()方法
如果使用treeset存放自定义类型的话,不在person类中实现compareable()接口,不重写compareto()的话,会报错ClassCastException,该异常可以在API查到。
比较器排序(实际开发常用,因为代码在控制曾层,相比在模型层更容易修改):自定义比较器类,实现comparator接口,实现compare方法。在treeset实例化对象后,使用add()方法,会自动调用comparator接口中的compare()方法。
从而实现排序,去重复(注意 treeset去除重复的 是通过 自己写的方法来实现的,并非和hashset一样,是重写hashcode()和equals()方法实现的)。
看到这,你会发现,他和 线程极其的像。看第一次线程的笔记
比较器的例子
匿名内部类实现 比较器
Treeset练习 :排序但不去重复
练习2 :
练习3 :升序不是降序,降序的话,为-1
还有就是: integer.parseInt();字符串型转换成整形
集合添加是一个一个添加的,所以集合的增加和String line = sc.nextline();放到while循环中。
- map 以及 hashmap
map<k,v> 和 collection<t> 是同一级别
双列集合的父接口,主要是hashmap和treemap
底层实现和set一模一样的,但是是双列的
Map集合的增删改查
Map实现遍历
使用 entrySet()方法实现遍历
加强for循环 :
在创建类对象的时候,只要重写了equals() 和hashcode() 即可实现。
- linkedhashmap<k,v>
凡是 前缀为 linkedhash的 都是唯一,且按照输入顺序录入数据的。
只不过又加了一个map,使得变成双列集合
- map集合框架
练习1
实现 字符串中的字母的个数
用TreeMap 或者 HashMap都行
练习2 嵌套
- hashtable
- collections 工具类 类似于操作数组的 arrays,对数组二分查找,排序
方法主要有这几个 都是静态方法collections.直接调用即可
附录 : 斗地主
package test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class PokerTest {
public static void main(String[] args) {
//demo1();
// 准备牌 hashmap 洗牌arraylist 发牌treeset
// 1 . 准备牌
HashMap<Integer, String> hm = new HashMap<>();
ArrayList<Integer> list = new ArrayList<Integer>();
String[] num = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
String[] coler = {"红桃", "黑桃", "梅花", "方片"};
int index = 0;
for (String n : num) {
for (String c : coler) {
hm.put(index, c.concat(n));
list.add(index);
index ++;
}
}
hm.put(index, "小王"); // 因为for 循环完了以后, i++ 了
list.add(index);
index++;
hm.put(index, "大王");
list.add(index);
// 2 . 洗牌
Collections.shuffle(list);
// 3 . 发牌
TreeSet<Integer> longwu = new TreeSet<Integer>();
TreeSet<Integer> gaojing = new TreeSet<Integer>();
TreeSet<Integer> me = new TreeSet<Integer>();
TreeSet<Integer> dipai = new TreeSet<Integer>();
for(int i = 0; i < list.size(); i++) {
if(i + 3 >= list.size()) {
dipai.add(list.get(i));
}else if(i % 3 == 0) {
longwu.add(list.get(i));
}else if(i % 3 ==1) {
gaojing.add(list.get(i));
}else{
me.add(list.get(i));
}
}
//看牌
System.out.println("gaojing");
for (Integer in : gaojing) {
System.out.print(hm.get(in) + ",");
}
System.out.println();
System.out.println("longwu");
for (Integer in : longwu) {
System.out.print(hm.get(in) + ",");
}
System.out.println();
System.out.println("me");
for (Integer in : me) {
System.out.print(hm.get(in) + ",");
}
System.out.println();
System.out.println("dipai");
for (Integer in : dipai) {
System.out.print(hm.get(in) + ",");
}
}
private static void demo1() {
// 1 . 准备牌
ArrayList<String> list = new ArrayList<String>();
String[] num = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
String[] coler = {"红桃", "黑桃", "梅花", "方片"};
for (String n : num) {
for (String c : coler) {
String str = c.concat(n);
list.add(str);
//System.out.println(str);
}
}
list.add("大王");
list.add("小王");
System.out.println(list);
// 2 . 洗牌
Collections.shuffle(list);
//3. 发牌
ArrayList<String> gaojing = new ArrayList<String>();
ArrayList<String> longwu = new ArrayList<String>();
ArrayList<String> me = new ArrayList<String>();
ArrayList<String> dipai = new ArrayList<String>();
for(int i = 0; i < list.size(); i ++) {
if(i >= 51) {
dipai.add(list.get(i));
}else if(i % 3 == 0) {
gaojing.add(list.get(i));
}else if(i % 3 ==1){
longwu.add(list.get(i));
}else if(i %3 == 2){
me.add(list.get(i));
}
}
// 4 看牌
System.out.println(dipai);
System.out.println(dipai.size());
System.out.println(longwu.size());
System.out.println(longwu);
System.out.println(gaojing);
System.out.println(gaojing.size());
System.out.println(me);
System.out.println(me.size());
}
}