集合
一、集合与数组优缺点
数组存取效率高,使用时要求容量大小固定;适合基本数据类型的存取;
集合存取效率上有一定的牺牲,集合容量大小可以根据实际需要改变,提供丰富的存取方法,适合成为对象的“容器”;
二、集合框架
Set、List、Collection、SortedSet均为接口,都存在实现类
三、Collection接口
集合框架的根
通用方法
boolean contains(Object a)
boolean equals(Object a)
Iterator iterator() //遍历
int size()
void clear()
boolean add(Object a)
remove(Object o)
addAll(Collection<? extends E> c)
四、Set接口
扩展Collection接口,不允许重复元素、没有排序、允许一个null值。
对 add()、元素的equals() 和 hashcode() 方法添加了限制、HashSet是其实现类。
1、集合存储
public class Demo {
public static void main(String[] args) {
Set set1 = new HashSet();
set1.add(true);
set1.add(null);
set1.add("a");
set1.add("a");
set1.add("b");
System.out.println(set1);
}
}
//并不会按照输入的顺序存储,输入重复的内容不会再次存储
//重复指示某个其他对象是否与此对象“相等”。
//注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
2、集合标准写法
Set<String> set1 = new HashSet<String>();
//声明了集合中可以存储的数据类型
3、简单案例
在具体案例中使用集合时,对象因地址不同,因此集合都会将这些对象进行存储,并不会对对象中的具体内容进行比较,所以在具体案例中,应该按照需求对方法进行重写。
//set实现不重复判断思路
//添加一个新的元素时,分别调用每个对象的hashcode方法,保存成功添加的hashcode值,以便快速查找对应的元素
//当出现一个新的元素与set中已有元素的hashcode值相同
// 调用新元素的equals方法进行逻辑判断,返回true,认为重复,添加不成功
// equals返回false,认为不重复,添加成功
//hashcode不同,直接添加新元素
下图案例为:当id相同的数据进行存储的时候,不会再存储进集合
4、Iterator迭代器(set接口中)
对集合进行迭代的迭代器,用于遍历里面的值
set.size();//获取集合的大小
for(String s:set){
System.out.print(s)
}//采用foreach循环遍历集合
Iterator<String> iterator = set.iterator();//获取set的迭代器
//Object next()返回迭代的下一个元素。
//boolean remove()从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。
boolean hasNext()如果仍有元素可以迭代,则返回 true。
最初始状态如下:hasNext()会指向最开始的位置
每次调用之后,hasNext()都会向下移动
//使用迭代器遍历集合
public class Demo {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("gok");
set.add("java");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
//System.out.println(iterator.next());不能同时取多次,当第一次用next()方法时,集合指针下面的第一个值已经被取走,无法再次提取。
}
}
}
boolean remove()
//从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。
//将指向集合的指针去掉
五、List接口
扩展了Collection接口
具有顺序的集合
元素可以通过其整型下标访问
可以包含重复元素
List<String> list = new ArrayList<String>();
1、List实现类
ArrayList类:
由一个数组后推而成,适合查询频繁的列表.
LinkedList类:
由一个双向链表后推而成,适合插入删除频繁的列表.
Vector:
实现可变长度的对象数组,组件可以使用整型下标访问,线程安全.
2、常用方法
①定位方法:
get()、set()、add()、remove()、addAll()
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("gok");
list.add("java");
list.add("GOK");
System.out.println(list);
}
}
//往集合中添加元素,List接口下的集合具有顺序
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
List<String> list1 = new ArrayList<String>();
list.add("gok");
list.add("java");
list.add("GOK");
list1.add("gok");
list.addAll(list1);
System.out.println(list);
}
}
//将list1集合添加至list集合中,List接口下的集合允许重复元素存在
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
List<String> list1 = new ArrayList<String>();
list.add("gok");
list.add("java");
list.add("GOK");
list1.add("gok");
list.addAll(list1);
System.out.println(list);
System.out.println("移除");
list.remove("gok");//按照内容移除
list.remove(0);
System.out.println(list);//按照位置移除
}
}
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("gok");
list.add("java");
list.add("GOK");
System.out.println(list);
System.out.println(list.get(0));//获取指定位置上的元素
list.set(0, "GOK");//更改指定位置上的元素
System.out.println(list.get(0));
System.out.println(list);
}
}
②搜索方法:
indexOf() 和 lastIndexOf()
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("gok");
list.add("java");
list.add("GOK");
list.add("gok");
System.out.println(list);
System.out.println(list.indexOf("gok"));//从第一个元素开始寻找"gok",并返回其位置
System.out.println(list.lastIndexOf("gok"));//从最后一个元素开始寻找"gok",并返回其位置
}
}
③ListIterator方法:
listIterator() 和 subList()
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("gok");
list.add("java");
list.add("GOK");
list.add("gok");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println("通用迭代器遍历" + iterator.next());
}
}
}
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("gok");
list.add("java");
list.add("GOK");
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {
System.out.println("ListIterator从头到尾遍历" + listIterator.next());
}
while (listIterator.hasPrevious()) {
System.out.println("ListIterator从尾到头遍历" + listIterator.previous());
}
}
}
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("gok");
list.add("java");
list.add("GOK");
List<String> subList = list.subList(0, 2);//迭代指定位置上的元素,包含头不包含尾
System.out.println(subList);
subList.clear();
System.out.println(subList);
System.out.println(list);
}
}
//subList实际上是在操作List集合,指针同时指向所需要的元素,若清空了subList,则List集合中,subList所指向的元素也被清空
六、Map接口
将键映射至值的对象<key,value>
每个键最多都只能映射至一个值,若键相同,则集合中的值更新为最新指向的值
1、Map实现类
HashMap
非线程安全(非同步),效率高
Hashtable
线程安全(同步),效率不如 HashMap
以键值对的形式存储数据
键被散列,散列码用作存储值的下标
2、常用方法
public class Demo {
public static void main(String[] args) {
Map map = new HashMap<>();
Map map1 = new HashMap<>();
map.put(1, "zs");
map.put("1", true);
map.put("2", 2);
map1.put(3, "gok");
map1.put(4, "gok");
System.out.println(map);
System.out.println(map.get("1"));//使用“键”找到“值”
Object ob1 = map.get(1);//只能使用Object类型接收
System.out.println(ob1);
map.remove(1);//通过“键”,删除存储内容
System.out.println(map);
System.out.println(map.size());//获取集合大小
System.out.println(map.containsKey("1"));//判断是否存在“键”为“1”的内容
System.out.println(map.containsValue("zs"));//判断是否存在“值”为“zs”的内容
map.putAll(map1);//集合整体添加
System.out.println(map);
map.clear();
System.out.println(map);//清空集合
}
}
public class Demo {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "zs");
map.put("2", "true");
map.put("3", "2");
System.out.println(map);
Set<String> keySet = map.keySet();//将集合中所有的“Key”放入Set集合
for (String str : keySet) {
System.out.println(str);
}
Collection<String> values = map.values();//将集合中所有的“values”放入Set集合
for (String str : values) {
System.out.println(str);
}
Set<Map.Entry<String, String>> entrySet = map.entrySet();//将集合中所有的键值放入Set集合
for (Map.Entry<String, String> entry : entrySet) {
System.out.println(entry);
}
}
}
七、Collections类
Collection接口的辅助工具类,提供静态的方法操作集合
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
System.out.println(list);
Collections.reverse(list);//反转集合
System.out.println(list);
}
}
//更多内容使用,查看API文档
八、枚举
Java 5.0引入了枚举,枚举限制变量只能是预先设定好的值。使用枚举可以减少代码中的bug。
例如:我们为果汁店设计一个程序,它将限制果汁为小杯,中杯,大杯。这就意味着它不允许顾客点除了这三种尺寸外的果汁。
九、可变参数
可变参数 是重载的另外一种写法
可变参数写法 num 代表 0个到多个Object 相当于 Object数组
可变参数的参数写法必须在参数列表的最后一列
public class Demo {
public static void speack(Object... num) {
System.out.println(num.length);
}
//Object定义可变参数可以接收任何数据类型
public static void main(String[] args) {
speack(1, 2, 3, 4);
speack(1);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oEfkzzVu-1620907450172)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210511154429129.png)]
例如:我们为果汁店设计一个程序,它将限制果汁为小杯,中杯,大杯。这就意味着它不允许顾客点除了这三种尺寸外的果汁。
九、可变参数
可变参数 是重载的另外一种写法
可变参数写法 num 代表 0个到多个Object 相当于 Object数组
可变参数的参数写法必须在参数列表的最后一列
public class Demo {
public static void speack(Object... num) {
System.out.println(num.length);
}
//Object定义可变参数可以接收任何数据类型
public static void main(String[] args) {
speack(1, 2, 3, 4);
speack(1);
}
}