Java集合
Java集合
- 参考文献:
https://www.runoob.com/java/java-collections.html
1、集合定义
-
集合是Java提供的一种容器,可以用来存储多个数据;
-
集合与数组的区别
- 数组长度是固定的,集合长度是可变的
- 数组存储的都是同一类型的元素,可以存储基本的数据类型,集合存储的都是对象,而且对象类型可以不一致(多态)。在开发中一般当对象多的时候,使用集合存储;
2、集合框架
-
集合按照存储结构分为两大类,分别是单列集合
java.util.Collection
和双列集合java.util.map
-
图示
2.1 Collection集合常用的方法
-
add(E e)添加
-
remove(E e)删除 返回布尔值
- 注意ArrayList的remove(索引)方法返回的是被删除的元素;!!!
-
clear() 清空所有的元素
-
contains() 判断是否包含某个元素
-
isEmpty() 判断集合长度是否为空
-
int size() 获取集合长度
-
Object[] toArray() 转换为数组
-
代码示例’
package day10; import java.util.ArrayList; import java.util.Collection; public class DemoMain { public static void main(String[] args) { //多态形式,声名集合 Collection<String> coll = new ArrayList<>(); coll.add("三体"); coll.add("流浪地球"); coll.add("章北海"); coll.add("东方延续"); Object[] obj=coll.toArray();//转换为数组; for (Object o:obj){//遍历数组 System.out.println(o); } System.out.println(coll); boolean res=coll.remove("流浪地球"); System.out.println(res); //查看是否包含 boolean isa=coll.contains("章北海"); System.out.println(isa); int s= coll.size(); System.out.println("长度"+s); coll.clear();//清空集合 boolean ist=coll.isEmpty(); System.out.println("是否为空"+ist); } }
2.2 Iterator迭代器
-
即
Collection
集合元素的通用获取方式。在取元素之前,先要判断集合中有没有元素,如果有,就把这个元素取出来,继续判断。如果还有,就再取出来。一直把集合中的元素全部取出来,这种取出方式专业术语称为迭代; -
Iterator接口的常用方法如下:
public E next():
返回迭代的下一个元素。public boolean hasNext()
:如果仍有元素可以迭代,则返回True.
-
原理图示
-
代码示例
package day10; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class DemoIter { public static void main(String[] args) { //1.创建集合对象 Collection<String> coll =new ArrayList<>(); //2.添加数据 coll.add("程心"); coll.add("韦德"); coll.add("比尔希恩斯"); coll.add("雷迪亚兹"); //3.使用迭代器进行访问 /* * 1.集合中的方法itrerator()获取迭代器的实现类对象,使用Iterator接口接收(多态) * 注意 * Iterator<E> 接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型 * */ //多态 接口 实现类对象 Iterator<String> it =coll.iterator();//方法itrerator()返回接口 //迭代元素结束,it.hashNext返回False; while(it.hasNext()){ String e= it.next(); System.out.println(e); } } }
-
补充增强for循环
for(类型 变量:目标){ ... } //注意,该形式必须要有被遍历目标,目标只能是Collection或者数组。
注意,该形式必须要有被遍历目标,目标只能是Collection或者数组。该形式的for仅仅作为遍历操作出现;
3、泛型
-
一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型;
-
创建对象的时候会确定泛型的数据类型;
3.1使用泛型的优劣对比
3.2 定义和使用含有泛型的类
package day10;
public class GenericClass <E>{
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
package day10;
public class DemoMain1 {
public static void main(String[] args) {
GenericClass<String> gc= new GenericClass<>();//实例化对象的时候确定泛型的类型
GenericClass<Integer> gc2= new GenericClass<>();//实例化对象的时候确定泛型的类型
gc.setName("hELLO world");
String name=gc.getName();
gc2.setName(12);
int x= gc2.getName();//自动拆箱
System.out.println(name);
System.out.println(x);
}
}
-
补充
3.3 定义使用含有泛型的接口
-
定义
package day10; public interface Gender <I>{ String func(I i); }
-
第一种实现方式(实现类不指定泛型的数据类型,实例化实现类对象的时候确定泛型的参数)
package day10; public class GenderImpl<I> implements Gender<I>{ @Override public void func(I i) { System.out.println(i); } }
package day10; public class DemoMain1 { public static void main(String[] args) { GenderImpl<String> gg= new GenderImpl<>(); gg.func("ssss"); GenderImpl<Double> ggg=new GenderImpl<>(); ggg.func(3.1415926); } }
-
第二种实现方式
-
实现类实现接口的时候直接指定接口的泛型类型
package day10; //实现类实现接口的时候直接指定接口的泛型类型 public class Gender2Impl implements Gender<String>{ @Override public void func(String s) { System.out.println(s); } }
-
笔记截图
3.4 泛型通配符
-
<?>
-
泛型之间不存在继承关系
-
package day10; import java.util.ArrayList; import java.util.Iterator; public class Test { public static void main(String[] args) { ArrayList<String> coll=new ArrayList<>(); coll.add("三体"); coll.add("流浪地球"); coll.add("章北海"); coll.add("东方延续"); ArrayList<Integer> list=new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); printArray(coll); printArray(list); //可以使用一个方法去遍历两个集合,而且类型不相同; //使用一个方法遍历两个集合 } public static void printArray(ArrayList<?> list){ Iterator<?> it =list.iterator(); while (it.hasNext()){ System.out.println(it.next()); } } }
-
补充了解:泛型的上下限
- 阅读源码是需要知道;限定通配符的使用类型
4、数据结构
4.1栈
- 特点:先进后出
4.2队列
- 特点:先进先出
4.3 数组
- 特点:查询快,增删慢;
4.4 链表
- 特点:增删快,查询慢;
4.5 红黑树
-
特点:趋*于*衡树,查询速度非常快;查询叶子节点的最大次数和最小次数不能超过两倍
-
约束
- 节点可以是红色或者黑色
- 根节点是黑色
- 叶子节点全是黑色
- 任何一个节点的所有路径上黑色节点数相同
5 、List集合
-
特点
- 有序集合,存储元素和取出元素的顺序是一致的
- 有索引,包含了一些带索引的方法
- 允许存储重复元素
-
特有的方法
- add
- get
- remove(索引)
- set(索引,新的值)
-
代码笔记
-
package day11; import java.util.ArrayList; import java.util.List; public class DemoList { public static void main(String[] args) { //使用多态的方法进行创建 List<String> ll=new ArrayList<>(); ll.add("a"); ll.add("b"); ll.add("c"); ll.add("d"); System.out.println(ll);//顺序不会改变 //修改,set 按照索引修改并返回被修改的元素 String s=ll.set(2,"Hello World"); System.out.println(s); //删除 remove 返回删除的元素 String r =ll.remove(3); System.out.println(r); System.out.println(ll); } } /* [a, b, c, d] c d [a, b, Hello World] */
5.1 ArrayList
- 底层由数组的复制实现,数组的增删(数组长度发生变化)是有地址的改变进行的
5.2 LinkedList
-
底层是链表结构,查询慢,增删快
-
里面包含了大量的首尾元素的方法
-
注意:Linkedlist 集合含有大量的特有方法,不能使用多态,
- 使用多态无法使用子类中特有的方法,需要进行类的转型,因此在此处不建议使用多态
package day11;
import java.util.LinkedList;
public class DemoLinkList {
public static void main(String[] args) {
show01();
System.out.println("============");
show02();
System.out.println("================");
show03();
System.out.println("============");
show04();
}
public static void show01(){
//addFirst与push方法都是在集合开头插入元素
LinkedList<String> list=new LinkedList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
System.out.println(list);
list.push("11");
list.addFirst("22");
System.out.println(list);
}
public static void show02(){
//add()与addlast方法都是在集合结尾插入元素,两方法等效
LinkedList<String> list=new LinkedList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
System.out.println(list);
list.add("11");
list.addLast("22");
System.out.println(list);
}
public static void show03(){
LinkedList<String> list=new LinkedList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
String s=list.getFirst();//返回列表的第一个元素
String s1=list.getLast();//返回列表的的最后一个元素
System.out.println(s+s1);
}
public static void show04(){
//pop与removelast
LinkedList<String> list=new LinkedList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
String first=list.removeFirst();//删除第一个元素并返回
System.out.println(first+"--------"+list);
String l1= list.pop();//删除第一个元素并返回;与上一个方法等效,
String l2=list.removeLast();//删除最后一个并返回;
System.out.println(l1+"--"+l2);
System.out.println(list);
}
}
5.3 Vector集合
- ArrayList集合的前身同步,jdk1.2后被ArrayList取代异步,目前使用不多;
6、Set接口
-
不允许存储重复元素
-
没有索引
-
不能使用普通的for循环遍历
-
底层是哈希表结构;查询非常快
-
package day11; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class DemoSet { public static void main(String[] args) { //多态创建对应的集合, //接口 Set<Integer> ss=new HashSet<>(); ss.add(1); ss.add(3); ss.add(2); ss.add(1);//不允许重复存储,存不进去 //使用迭代器遍历集合 Iterator<Integer> it=ss.iterator(); while (it.hasNext()){ System.out.println(it.next()); } //增强for for(int i:ss){ System.out.println(i); } } }
6.1HashSet集合
-
hash值
-
数据结构
-
不重复原理
-
存储自定义的元素
package day11; import java.util.Objects; public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } //重写method和equals方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } package day11; import java.util.HashSet; import java.util.Set; public class DemoMain { public static void main(String[] args) { //object类中包含hashcode方法,要是往集合中存储自定义的类对象,就必须重写对应的hashcode()和equal()方法 //HashSet存储时先判断hash值,再判断内容(equal) Set<Person> set=new HashSet<>(); Person p1=new Person("傻狗",12); Person p2=new Person("傻狗",12); Person p3=new Person("傻狗",16); System.out.println(p1.hashCode()); System.out.println(p2.hashCode()); System.out.println(p3.hashCode()); set.add(p1); set.add(p2); set.add(p3); System.out.println(set); } }
6.2 LinkedHashSet
- 支持存储的顺序,原来是什么顺序取出还是什么顺序;
7、可变参数
-
package day11; public class DemoDut { public static void main(String[] args) { printpp("a","a","c"); } //可变参数 public static void printpp(String...s){ //s的数据类型为可变数组 for (String s1 : s) { System.out.println(s1); //Console: a a c } } }
-
注意事项:
- 一个方法的参数列表只能有一个可变参数
- 如果方法的参数有多个,那么可变参数必须在写在参数列表的末尾;
-
终极写法
public static void method(Object...obj){ //可以接收任意的数据类型 }
8、集合工具类
-
java.utils.collections
集合的工具类 -
常见方法
-
addAll(Collection<? super T> c, T... elements)
将所有指定的元素添加到指定的集合中。 -
shuffle(List<?> list)
随机置换指定列表使用随机默认源。打乱顺序 -
sort排序(建议用的时候进行百度)
-
-
package day11; import java.util.ArrayList; import java.util.Collections; public class DemoMain1 { public static void main(String[] args) { ArrayList<Integer> list= new ArrayList<>(); //添加多个 Collections.addAll(list,1,2,5,3,4,6,0); System.out.println(list); //默认排序 Collections.sort(list);//升序 System.out.println(list); //打乱顺序 Collections.shuffle(list); System.out.println(list); } }
9、Map集合
-
概述
-
hashMap的特点
-
常用方法
- put添加
- remove移除返回
- get(key)获取
package day12; import java.util.HashMap; import java.util.Map; public class DemoHashSet { public static void main(String[] args) { Map<String,Integer> map=new HashMap<>(); map.put("k1",1); map.put("k2",1); map.put("k3",1); map.put("k4",1); map.put("k5",1); System.out.println(map); map.put("k1",3); System.out.println(map);//重复写入值不一样可以看做修改,没有修改的函数 Integer k1 = map.get("k1");//如果这里使用的int可能会存在空值;造成异常 //int k2 = map.get("k9");//造成异常 System.out.println(k1); Integer k5 = map.remove("k5"); System.out.println(k5); System.out.println(map); } } //consloe /* {k1=1, k2=1, k3=1, k4=1, k5=1} {k1=3, k2=1, k3=1, k4=1, k5=1} 3 1 {k1=3, k2=1, k3=1, k4=1} */
9.1遍历Map集合
-
KeySet
-
package day12; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import java.util.Map; public class DemoMain { public static void main(String[] args) { Map<String,Integer> map=new HashMap<>(); map.put("k1",1); map.put("k2",1); map.put("k3",1); map.put("k4",1); map.put("k5",1); Set<String> set=map.keySet(); Iterator<String> it=set.iterator(); while (it.hasNext()){ String key=it.next(); System.out.println(map.get(key)); } System.out.println("========"); for(String s:map.keySet()){ System.out.println(map.get(s)); } } }
-
-
第二种遍历方式
-
存储自定义的元素
- 当自定义的类当做键的时候需要重写hashcode和equals方法;
-
Hashtable
10、Java中使用Json
-
参考文献:
https://www.cnblogs.com/undead/archive/2012/07/18/2594900.html
-
import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; //声明一个Hash对象并添加数据 Map params = new HashMap(); params.put("username", username); params.put("user_json", user); //声明JSONArray对象并输入JSON字符串 JSONArray array = JSONArray.fromObject(params); put.println(array.toString()); //直接将集合转换成json对象;
将字符串转换成字符串此处不在展示,请查看参考文献;
对比:勿混淆
-
Python中的集合
-
{1,2,3}#集合是Python的一种基本数据类型;不允许重复存储
-
-
Python中的列表
-
[]#列表可以增加,删除,获取,修改类似与ArrayList,但是类型不限制
-
-
Python中的字典
-
{"k1","v1"}#键值对的形式,可以直接转换成json的形式较方便 import json json.dumps(dict)
-