集合的概念
- 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能
- 和数组的区别:
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型
- 位置: java.util.*
Collection接口
package study;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo {
public static void main(String[] args){
//Collection是父接口,用ArrayList实现
Collection collection=new ArrayList();
//add() 添加对象
collection.add("苹果");
collection.add("西瓜");
collection.add("榴莲");
//size() 返回对象个数
System.out.println("元素个数"+collection.size());
System.out.println(collection);
// remove() 删除集合括号内容
// collection.remove("榴莲");
//clear() 清空
// collection.clear();
//增强for输出集合
for (Object object : collection) {
System.out.print(object+" ");
}
System.out.println();
System.out.println("-------使用迭代器--------");
//iterator() 迭代器
Iterator it=collection.iterator();
//使用迭代器进行迭代
//hasnext() 判断有没有下一个元素
while (it.hasNext()) {
//next() 获取下一个元素
String str = (String) it.next();
System.out.print(str+" ");
//不能再迭代器中使用collection的删除方法
// collection.remove("苹果");
//迭代器里的 remove() 删除一个元素
it.remove();
}
//结果 元素个数0
System.out.println("元素个数"+collection.size());
//isEmpty() 判断集合是否为空
System.out.println(collection.isEmpty());
//contains() 判断集合是否包含括号内容
System.out.println(collection.contains("西瓜"));
}
}
List接口与实现类
List的使用
package study;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.ListIterator;
public class Demo {
public static void main(String[] args) {
// 创建子接口
List list = new ArrayList<>();
list.add("苹果");
list.add("小米");
list.add(0, "华为");
// list有下标可以for循环遍历
for (int i = 0; i < list.size(); i++) {
//get() 获取指定位置元素
System.out.println(list.get(i));
}
System.out.println("-------------------");
//使用迭代器
Iterator it = list.iterator();
while (it.hasNext()) {
// String str = (String) it.next();
System.out.println(it.next());
}
System.out.println("------使用列表迭代器正向遍历-------");
//创建列表迭代器对象,和迭代器区别:列表迭代器可以选择方向遍历,添加丶删除丶修改元素
ListIterator lit = list.listIterator();
//hasNext() 正向遍历是判断是否有下一个元素
while (lit.hasNext()) {
//nextIndex() 返回对next的后续调用所返回元素的索引
//next() 返回列表的下一个元素
System.out.println(lit.nextIndex() + " " + lit.next());
}
System.out.println("------使用列表迭代器逆向遍历-------");
//hasPrevious() 逆向遍历时,判断是否有下一个元素
while (lit.hasPrevious()) {
//previousIndex() 返回对previous的后续调用所返回元素的索引
//previous() 返回列表的前一个元素
System.out.println(lit.previousIndex() + " " + lit.previous());
}
//判断是否存在括号元素
System.out.println(list.contains("苹果"));
//判断集合是否为空
System.out.println(list.isEmpty());
//indexOf() 返回括号元素下标
System.out.println(list.indexOf("华为"));
System.out.println("------------------------------");
List list1=new ArrayList();
//自动装箱
list1.add(20);
list1.add(30);
list1.add(40);
list1.add(50);
System.out.println(list1.toString());
//remove() 删除索引元素
// list1.remove(0);
list1.remove(new Integer(20));
//subList() 返回子集合 含头不含尾
List subList=list1.subList(1,3);
//结果 [30, 40]
System.out.println(subList.toString());
}
}
List的实现类
ArrayList使用
Vector使用
package study;
import java.util.Enumeration;
import java.util.Vector;
public class Demo {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add("12");
vector.add("13");
vector.add("15");
//使用枚举器
Enumeration en= vector.elements();
while (en.hasMoreElements()) {
String object = (String) en.nextElement();
System.out.println(object);
}
}
}
LinkedList使用
链式
泛型和工具类
泛型
- java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,吧类型作为参数传递
- 常见形式有泛型类丶泛型接口丶泛型方法
- 语法: <T…> T称为类型占位符,表示一种引用类型
- 好处:
- 提高代码的重用性
- 防止类型转换异常,提高代码的安全性
泛型类
package study;
public class Generic <T>{
T t;
public void show(T t) {
System.out.println(t);
}
public T getT() {
return t;
}
}
package study;
public class Demo {
public static void main(String[] args) {
//泛型只能使用引用类型
Generic<String> generic=new Generic<String>();
generic.t="zhangsan";
generic.show(generic.t);
System.out.println(generic.getT());
Generic<Integer>generic2 =new Generic<>();
generic2.t=22;
generic2.show(generic2.t);
//报错,不同泛型对象之间不能相互赋值
// generic.t=generic2.getT();
}
}
泛型接口
//父接口
package study;
public interface MyInterface<t> {
String name="zhangshan";
T server(T t);
}
//两种实现父接口方式
//一丶 直接定义类型
package study;
public class MyInterfaceImpui implements MyInterface<String>{
@Override
public String server(String t) {
System.out.println(t);
return t;
}
}
//二丶调用时确实类型
package study;
public class Myinterfacelmpl<T> implements MyInterface<T> {
@Override
public T server(T T) {
System.out.println(T);
return null;
}
}
package study;
public class Test {
public static void main(String[] args) {
//方式一
MyInterfaceImpui name = new MyInterfaceImpui();
name.server("张三");
//方式二
Myinterfacelmpl<Integer> name1 = new Myinterfacelmpl<Integer>();
name1.server(45);
}
}
泛型方法
//注意<T> 要在返回类型前面
//不定义参数类型,由调用方法时输入的数据类型确定
package study;
public class Generic <T>{
public static <T> T show(T t) {
return t;
}
}
package study;
public class Demo {
public static void main(String[] args) {
System.out.println(Generic.show("李四"));
System.out.println(Generic.show(12));
}
}
泛型集合
package study;
import java.util.ArrayList;
import java.util.Iterator;
public class Demo {
public static void main(String[] args) {
// ArrayList list2=new ArrayList();
// list2.add(21);
// list2.add("aaa");
// for (Iterator iterator = list2.iterator(); iterator.hasNext();) {
//集合遍历需要强制类型转换,并且存在不同类型数据遍历会报错
// String object = (String) iterator.next();
// System.out.println(object);
// }
ArrayList<Integer> list = new ArrayList<>();
list.add(21);
list.add(11);
for (Integer integer : list) {
//泛型集合不需要强制类型转换,可以正常遍历
System.out.println(integer);
}
}
}
Set接口与实现类
Set接口
-
特点:无序丶无下标丶元素不可重复
-
方法:全部继承自Collection中的方法
package study; import java.util.HashSet; import java.util.Set; public class Demo { public static void main(String[] args) { //用HashSet实现Set子接口 Set<Integer> set=new HashSet<>(); set.add(3); set.add(1); set.add(2); set.add(2); //存入元素不重复 //结果 元素个数:3 System.out.println("元素个数:"+set.size()); //无序存入 //结果 [1, 2, 3] System.out.println(set.toString()); //删除数据 //遍历操作 //使用迭代器 //判断 } }
Set实现类
- HashSet(重点):
- 基于HashSet实现元素不重复
- 当存入元素的哈希码相同是,会调用equals进行确认,如结果为true,则拒绝后者存入
package study;
import java.util.HashSet;
public class Demo {
public static void main(String[] args) {
HashSet<Integer> set = new HashSet<>();
set.add(3);
set.add(1);
set.add(2);
set.add(2);
// 存入元素不重复
// 结果 元素个数:3
System.out.println("元素个数:" + set.size());
// 无序存入
// 结果 [1, 2, 3]
System.out.println(set.toString());
//删除数据
//遍历操作
//使用迭代器
//判断
}
}
//HashSet的存储方式
//存储结构:哈希表(数组+链表+红黑树)
//存储过程:根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空,再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链条
package study;
import java.util.HashSet;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
HashSet<Student> hashSet=new HashSet<>();
//学生类中定义了年龄和姓名属性
Student p1 = new Student(12,"李四");
Student p2 = new Student(13,"张三");
Student p3 = new Student(12,"李四");
hashSet.add(p1);
hashSet.add(p2);
hashSet.add(p3);
hashSet.add( new Student(12,"李四"));
//没有重写hashcode和equals返回数值为4
//重写后返回2
System.out.println(hashSet.size());
for (Student student : hashSet) {
System.out.println(student);
}
}
}
-
TreeSet:
-
基于排列顺序实现元素不重复
-
实现了SortedSet接口,对集合元素自动排序
-
元素对象的类型必须实现Comparable接口,指定排序规则
-
通过CompareTo方法确认是否为重复元素
/* 使用TreeSet保存数据 存储结构:红黑树 要求:元素必须要实现Comparable接口,compareTO方法返回值为0,认为是重复元素 */ package study; //实现接口 public class Student implements Comparable<Student> { int age; String name; public Student(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student [age=" + age + ", " + (name != null ? "name=" + name : "") + "]"; } //实现接口方法 @Override public int compareTo(Student o) { //用compareTo()方法比较姓名 int n1=this.getName().compareTo(o.getName()); int n2=this.getAge()-o.getAge(); //返回值为0,则认为是重复元素 return n1==0?n2:n1; } } package study; import java.util.Iterator; import java.util.TreeSet; public class Test { public static void main(String[] args) { TreeSet<Student> treeSet = new TreeSet<>(); Student p1 = new Student(12, "李四"); Student p2 = new Student(13, "张三"); Student p3 = new Student(12, "李四"); //必须实现接口才能添加至TreeSet对象 treeSet.add(p1); treeSet.add(p2); treeSet.add(p3); treeSet.add(new Student(12, "李四")); System.out.println(treeSet.size()); for (Student student : treeSet) { System.out.println(student); } } }
Comparator接口
package study; public class Student { int age; String name; public Student(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student [age=" + age + ", " + (name != null ? "name=" + name : "") + "]"; } } package study; import java.util.Comparator; import java.util.TreeSet; public class Test { public static void main(String[] args) { //Comparator接口实现定制比较 //通过实现内部匿名类Comartator接口完成TreeSet对象的输入 //创建集合,并指定比较规则 TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int n1=o1.getAge()-o2.getAge(); int n2=o1.getName().compareTo(o2.getName()); return n1==0?n2:n1; } }); Student p1 = new Student(12, "李四"); Student p2 = new Student(13, "张三"); Student p3 = new Student(12, "李四"); treeSet.add(p1); treeSet.add(p2); treeSet.add(p3); treeSet.add(new Student(12, "李四")); System.out.println(treeSet.size()); for (Student student : treeSet) { System.out.println(student); } } }
-
Map接口与实现类
Map父接口的使用
特点:1.存储键值对
2.键不能重复,值可以重复
3.无序
package study;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Map<String, String> map=new HashMap<>();
//put() 添加
map.put("cn","中国");
map.put("uk","英国");
map.put("usa","美国");
map.put("cn","zhongguo");
System.out.println("元素个数"+map.size());
System.out.println(map.toString());
// map.remove("cn");
//遍历
// System.out.println(map.toString());
//keySet() 返回键
// Set<String> kSet=map.keySet();
for (String key : map.keySet()) {
System.out.println(key);
}
System.out.println("----entrySet----");
//entrySet() 返回键丶值
Set<Map.Entry<String, String>> entries= map.entrySet();
for (Map.Entry<String, String>entry : entries) {
System.out.println(entry.getKey()+"---"+entry.getValue());
}
//判断是否存在内容
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("美国"));
}
}
总结:
- HashMap刚创建时,table是null,为节省空间,当添加第一个元素时,table容量调整为16
- 当元素个数大于阀值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍 ,目的是调制元素个数
- jdk1.8当每个链表长度大于8,并且元素个数大于等于64时,会调整为红黑树,目的是调高执行效率
- jdk1.8 当链表小于6时,调整成链表
- jdk1.8以前链表是头插入,jkd1.8以后是尾插入
实现类
- HashMap(重点)
- TreeMap:实现了SortedMap接口(是Map的子接口),可以对可以自动排序
- TreeMap是通过compaerTO方法或通过实现内部匿名类Comartator接口实现比较
ColletionS工具类
概念:集合工具类,定义除了存取以外的集合常用方法
package study;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();
list.add(22);
list.add(45);
list.add(12);
list.add(95);
list.add(60);
System.out.println(list.toString());
//sort排序(默认升序)
Collections.sort(list);
System.out.println(list.toString());
//binarySearch二分查找 如果存在所查找的元素则返回相应位置 不存在则返回一个负数
int i=Collections.binarySearch(list, 22);
System.out.println(i);
//创建并初始化目标数组
List<Integer> dest=new ArrayList<>();
for (int j = 0; j < list.size(); j++) {
dest.add(0);
}
//copy复制
Collections.copy(dest, list);
System.out.println(dest.toString());
//反转
Collections.reverse(list);
System.out.println("反转之后:"+list);
//打乱
Collections.shuffle(list);
System.out.println("打乱之后:"+list);
//补充方法
//toArray()集合转成数组
//转换数组的长度小于集合,则数组长度等于集合长度,如果大于,多余数组内容为空
Integer[] arr= list.toArray(new Integer[6]);
System.out.println(Arrays.toString(arr));
String[] names= {
"张三","李四","王五"};
//Arrays.asList数组转集合
//集合是一个受限集合,不能添加和删除
List<String> list2= Arrays.asList(names);
System.out.println(list2);
//基本数据类型数组转成集合是,需要修改为包装类型
// int [] nums= {1,2,3};
// List<int[]> list3= Arrays.asList(nums); 此时集合中存储的是数组,不是数据
Integer [] nums= {
1,2,3};
List<Integer> list3= Arrays.asList(nums);
System.out.println(list3);
}
}