Java 基础 --- 集合框Java 基础 --- 集合框 变量 可以用来存储数据,但一次只能存储一个; 数组 可以用
Java 基础 --- 集合框
变量 可以用来存储数据,但一次只能存储一个;
数组 可以用来存储同一个数据类型的数据,也可以存储复合类型的数据 --- 类,但数组必须指定大小,一旦指定就不会改变;所以,为了解决数组是有大小限制和类型限制导致不能随便存放数据这个问题(不灵活),所以就产生了集合。
Collection
集合是一种java中用来装数据的一个类,是一个容器,可以存储多种数据,根据存储的数据类型或需要的操作不一样,就形成了java中的集合框架;
Collection、Map 是两个接口,它们就引出了集合框架;
Collection 它有两个子接口,分别是:list; set;
list 是一个子接口它有它的实现类:arraylist ; linkedlist;
Set 也是一个子接口,它的实现类是:hashset ; treeset;
List、Set 是Collection 集合的继承接口;跟他之间是一个继承的关系;
arraylist、 linkedlist 、hashset 、treeset都是实现类,
在存储数据时,他就是使用 Array(数组)、Linked(链表)、Hash(哈希表)、 Tree(树) 这些结构来存储。
List: 它是列表,他存储的数据是有顺序的,可以重复放入数据;
Set: 它存储的数据是没有顺序的,并且不可以放入重复数据,就算放入重复数据,最后也只有一个;
List接口:(有顺序,能重复)
实现类:
Arraylist: 底层使用数组来存储数据;它进行数据查询比较快(随机查询),经常用于查询操作;
Linkedlist: 底层使用的是链表,通常用来修改数据,删除数据,添加数据速度比较快;
Stack: 栈 是java已经封装好的,可以进行栈的各种操作:先进后出,已经写好的直接调就可以;
Vector: 向量 --- 可变数组,大小可变;
List
使用Arraylist来存储数据
public static void main(String[] args) {
// 通过Arraylist来存储数据,要创建他的对象;
List list = new ArrayList();//多态的体现
// 开始装数据
list.add("xiaoxiao");
list.add(123);
list.add(true);
// 查看数据
System.out.println(list);
System.out.println(list.size());
System.out.println(list.get(0));
System.out.println("用for循环直接遍历:");
// 用for循环直接遍历它
for (int i = 0;i <list.size();i++){
System.out.println(list.get(i));
}
System.out.println("迭代器(foreach)遍历:");
// 在用迭代器(foreach)再次遍历它
for (Object object:list) {
System.out.println(object);
}
System.out.println("----------------");
// 修改数据
list.set(1,"李四");
System.out.println(list.get(1));
System.out.println("----------------");
// 删除数据
list.remove(1);
//list.remove("lisi");//也可以使用直接删除已有的字符串
System.out.println(list.get(1));
}
public static void main(String[] args) {
// 通过Arraylist来存储数据,要创建他的对象;
List list = new ArrayList();//多态的体现
// 开始装数据
list.add("xiaoxiao");
list.add(123);
list.add(true);
// 查看数据
System.out.println(list);
System.out.println(list.size());
System.out.println(list.get(0));
System.out.println("用for循环直接遍历:");
// 用for循环直接遍历它
for (int i = 0;i <list.size();i++){
System.out.println(list.get(i));
}
System.out.println("迭代器(foreach)遍历:");
// 在用迭代器(foreach)再次遍历它
for (Object object:list) {
System.out.println(object);
}
System.out.println("----------------");
// 修改数据
list.set(1,"李四");
System.out.println(list.get(1));
System.out.println("----------------");
// 删除数据
list.remove(1);
//list.remove("lisi");//也可以使用直接删除已有的字符串
System.out.println(list.get(1));
}
实现效果:
使用Linkedlist来实现
public static void main(String[] args) {
// 使用linkedlist来实现
// 创建linkedlist对象
List list = new LinkedList();
LinkedList linkedList = (LinkedList) list;//向下转型--强制转换
// 查看集合的大小
list.add("张三");
list.add(1234);
list.add(new String("aaa"));
// 添加一个类
list.add(new Student(001, "xiaoxiao1", "beijing"));
list.add(new Student(002, "xiaoxiao2", "beijing"));
// 插入数据(头部和尾部) 这里使用的linkedlist方式来存储数据,所以我们就需要在创建一个linkedlist的对象
linkedList.addFirst("first");//在头部插入
linkedList.addLast(11231);//在尾部插入
linkedList.add(2, "second");
System.out.println(list);
// 删除数据
linkedList.removeFirst();//删除第一个
linkedList.removeLast();//删除最后一个
linkedList.remove("first");//删除指定数据
linkedList.remove(3);//删除指定位置
// 查询数据
linkedList.getFirst();//获取第一个
linkedList.getLast();//获取最后一个
linkedList.get(4);//获取指定位置
System.out.println("for循环查询全部:");
// 获取全部使用遍历的方式
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
System.out.println("foreach遍历查询全部:");
for (Object object :linkedList) {
System.out.println(object);
}
}
实现效果:
下面是我写的一个例子:
首先是一个学生类,学生里面有id,name,address属性,通过在Student类里面封装方法,生成get和set方法、生成toString方法、生成构造方法,然后用Test_Student类来对student类里面的属性进行增删改查,我用Arraylist这个实现类来实现当然也可以换成其他实现类来实现。
student.class:
public class Student {
private int id;
private String name;
private String address;
// 对方法进行封装
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
// 生成构造方法
public Student(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
// 生成toString方法
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
我把泛型这个知识点补充在这里啦,从这里了解完下面的代码就迷糊啦!!!
泛型
ArrayList<E> arrayList=new ArrayList<E>();
你可以简单理解为它是一个类型;广泛的类型;
其实他是一种参数;主要是在你的类或者接口类型不确定的时候我们使用泛型来指定;
在使用的时候不知道类型; 就是泛型来指定; 就是广泛的类型;
泛型可以用来 类---泛型类; 接口---泛型接口; 方法上---泛型方法; 就是你这个类; 你这个接口; 你这个方法里边的参数不确定的时候; 就用泛型来代替;
例如:
不知道去食堂吃饭吃什么; 就可以泛型来指定; 就是广泛类型; 在你去了食堂才知道你到底吃啥;
如果我们在定义集合的时候: 没有指定集合泛型;
从你的集合中取出来的内容就是 object类型的数据; 需要类型的转换; 需要的是多态的向下转型;
((Student)object).getId() 才可以把你的object对象转换为 student;
泛型的具体的在代码中的体现:
ArrayList arrayList=new ArrayList();//他里边就是object对象;
ArrayList<Student> arrayList2=new ArrayList<Student>();// 里边放入的就是student类型或者是他子类对象
ArrayList<String> arrayList3=new ArrayList<String>();
当你以后再代码中不知道你要写的是啥的时候; 使用泛型来代替; object;
ArrayList<Student> arrayList=new ArrayList<Student>();
他就是指定这个集合中放入的数据是student类型的; 以及他的子类类型;
以后当我们不知道他是什么类型的时候; 你直接放入object; 或者把删除;没有就是你的对象 object;
Test_Student:
public static void main(String[] args) {
// 使用泛型,指定类型
ArrayList<Student> arrayList = new ArrayList<Student>();
// 分别添加三组信息
arrayList.add(new Student(123,"xiaoxiao1","beijing"));
arrayList.add(new Student(234,"xiaoxiao2","beijing"));
arrayList.add(new Student(345,"xiaoxiao3","beijing"));
// 修改信息
// arrayList.set(2,new Student(111,"xiaoxiao11","shanghai"));
// 删除信息
// arrayList.remove(1);
// 查询所有数据
for (Student student: arrayList) {
System.out.println(student);
}
}
部分操作被我注释了,如果需要的话直接拿过去解开注释就可以啦;
实现效果:
Set
Collection 的另外一个子接口 :Set
Set 它和 List 是兄弟关系,是用来 存储数据的,它有两个实现类:
HashSet 和 TreeSet;
HashSet: 底层使用 Hash表 来进行数据存储的;
TreeSet :底层使用 红黑树 来存储数据;
特点
在进行存储数据的时候它会对数据进行判断:
Set中的数据是否存在,如果有了数据,它就不要这个数,也就是做一个 去重操作 ,它里边只会存储一份数据,它会做 去重操作 操作的原因是 Set 里边有一个比较器,存储数据时都会进行比对,List 则没有 ;
HashSet 存储
如果在开发过程中,遇到不允许数据重复的情况下,那么就可以直接把数据存储到HashSet中;
HashSet 存储的数据是没有顺序的,它使用的是HashMap ,而HashMap的底层就是Hash 表;
public static void main(String[] args) {
Set set =new HashSet();
// 添加数据
set.add("积水成江");
set.add("xiaoxiao");
set.add("xiaoxiao");
set.add("xiaoxiao");
// 查询数据
System.out.println(set);
// 查看集合长度
System.out.println(set.size());
// 查看集合中是否有需要查找的元素,返回一个布尔值
System.out.println(set.contains("xiaoxiao"));
// 也可使用迭代器来遍历集合
Iterator iterable = set.iterator();
while (iterable.hasNext()){
String str = (String)iterable.next();
System.out.println(str);
}
}
TreeSet 存储
TreeSet 的底层使用的是红黑树的方式进行存储数据,它的操作和 HashSet 操作一样,唯一不一样的是: HashSet 不会对数据排序;**TreeSet ** 可以排序,并且按照自然顺序排序(A-Z,0—9);
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add("a");
treeSet.add("t");
treeSet.add("v");
treeSet.add("q");
treeSet.add("3");
treeSet.add("1");
treeSet.add("9");
treeSet.add("7");
System.out.println(treeSet);
}
Map
Map (映射)是另外一个接口,它和Collection 是同辈关系,它俩没有直接关系;
原理
Map 的底层是通过键值对的方式存储数据,是映射关系,通过key 映射Value :
Key(键:唯一的不能重复),Vaule(可以重复出现), 如果map中有重复的key,则会被覆盖掉;
他的实现类有两个:
HashMap
HashMap: 底层是用哈希表来存储,操作数据的时候会使用哈希算法来进行,里面的 key 就是Hash表中的索引位置,也可以理解为Map中的Key是一个set 它会去重,它里面的值不会排序,只会根据键的自然排序进行排序;
// 统计每个字符出现的次数
public static void main(String[] args) {
String str = "asadsasfszasewwsdredffdhghiyugfsaaddcf";
// 先把字符串转换为数组
char charArr[] = str.toCharArray();//把字符转换为字符数组
// Character、Integer他俩是包装类,就是把key(不允许重复)放在Character(这个位置上的数据是不允 许重复的)存储字符串,Integer代表value值统计出现的次数
Map<Character,Integer> map = new HashMap();//创建一个Map对象
// 把数组进行迭代
for (char c: charArr) {
// 开始判断map中是否有数据
if(map.containsKey(c)){//检查map中的键是否和c(把数据里面的值拿出来)相同,如果相同就执行 下面的语句,否则进else
// 这里有一个过程就是:第一次走的时候c里面是空的,走完一次然后把c里面的值取出来,然后在把第一次取出 来的值做参照来统计后面值出现的次数
// 把Map里面的值放到计数器里面
Integer count = map.get(c);//如果map中有这个key,那么把key对应的值拿出来+1
map.put(c,count+1);
}else{
// 第一次走的时候c为空,使用所以直接来到了else
map.put(c,1);//map通过put放入数据到key上;
}
}
System.out.println(map);//打印map
}
查询数 --- 使用迭代器
使用迭代器的方式有很多,这里就只说三种吧:
1️⃣ 使用Map.Entry来实现:
public static void main(String[] args) {
Map<Integer,String> map2 = new HashMap<Integer,String>();
map2.put(7,"777");
map2.put(9,"99");
map2.put(1,"11");
map2.put(5,"55");
map2.put(2,"22");
map2.put(6,"6");
map2.put(10,"10");
//把map中的数据通过迭代得到一个迭代器
Iterator<Map.Entry<Integer,String>>iterator = map2.entrySet().iterator();
while (iterator.hasNext()){//对迭代器进行迭代
Map.Entry<Integer,String>next = iterator.next();
System.out.println("key:"+next.getKey()+"\t"+next.getValue());
}
}
2️⃣ 使用keySet来实现:
public static void main(String[] args) {
Map<Integer,String> map2 = new HashMap<Integer,String>();
map2.put(7,"777");
map2.put(9,"99");
map2.put(1,"11");
map2.put(5,"55");
map2.put(2,"22");
map2.put(6,"6");
map2.put(10,"10");
// 使用keySet来实现
for (Integer key :map2.keySet()) {
System.out.println(key+"\t"+"获取你的值:"+map2.get(key));
}
}
3️⃣使用EntrySet来遍历
public static void main(String[] args) {
Map<Integer,String> map2 = new HashMap<Integer,String>();
map2.put(7,"777");
map2.put(9,"99");
map2.put(1,"11");
map2.put(5,"55");
map2.put(2,"22");
map2.put(6,"6");
map2.put(10,"10");
// 使用EntrySet来遍历
Set<Map.Entry<Integer,String>> set = map2.entrySet();
for (Map.Entry<Integer,String> entry :set) {
System.out.println("key:"+entry.getKey()+"\t"+"value:"+entry.getValue());
}
}
TreeMap
TreeMap :底层使用的是红黑树的算法来实现,因为map中的key是set它能够保证数据不重复,他的键是根据自然排序的;
public static void main(String[] args) {
Map<String, Student> map = new TreeMap<String,Student>();
map.put("g",new Student(6,"g6","qq"));
map.put("a",new Student(9,"a9","qq"));
map.put("j",new Student(1,"j1","qq"));
map.put("l",new Student(3,"l3","qq"));
for (String str: map.keySet()) {
// 获取键我们要根据它的值去接
Student student = map.get(str);
System.out.println(str+"\t"+student.getId()+"\t"+student.getName()+"\t"+student.getAddress());
}
总结:
如果存储的数据是重复数据,使用 List;
如果存储的数据不允许出现重复值,使用 Set;
如果存储的数据是key值:value值,则使用Map存储。
今天的分享就到这里啦,小江会一直与大家一起努力,文章中如有不足之处,还请指出哦,感谢支持,持续更新中 ……
转载自:https://juejin.cn/post/7426282622723457061