集合
集合概念:
对象的容器,实现了对对象的操作,类似数组的功能。
Collection接口
1.Collection父接口
特点:代表一组任意类型的对象,无序,无下表,不能重复。
方法:
- boolean add(Object obj) //添加一个对象
- boolean addAll(Collection c) //将一个集合中的所有对象添加到此集合中。
- void clear() //清空此集合中所有对象。
- boolean contains(Object o) //检查是否包含o对象
- boolean equals(Object o) //判断此集合是否与指定对象相等
- boolean isEmpty() //判断此集合是否为空
- boolean remove(Object o) //在此集合中移除o对象
- int size() //返回此集合中的元素个数
- Object[] toArray() //将此集合转换成数组
/**
*Collection接口的使用
* @author chengcheng
* 1.添加元素
* 2.删除元素
* 3.遍历元素
* 4.判断
*
*/
public class Demo1 {
public static void main(String[] args) {
//创建集合
Collection collection = new ArrayList();
collection.add("西瓜");
collection.add("苹果");
collection.add("榴莲");
System.out.println("元素个数:"+collection.size());
System.out.println(collection); //[西瓜, 苹果, 榴莲]
//删除元素
// collection.remove("西瓜");
// collection.clear();
// System.out.println("删除后:"+collection.size());
//遍历元素
//collection没有下标,不能用for遍历,但能用增强for
//(1)使用增强for
for (Object object : collection) {
System.out.println(object);
}
//(2)使用迭代器(专门用来遍历集合的一种方式)
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
String s=(String) iterator.next();
System.out.println(s);
// collection.remove(s); //迭代的过程不能使用Collection中的remove这个方法,
// iterator.remove(); //只能使用迭代器的这个方法
}
System.out.println(collection.size());
//判断
System.out.println(collection.contains("西瓜"));
System.out.println(collection.isEmpty());
}
}
使用Collection存储对象
创建一个Student类
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Demo2 {
public static void main(String[] args) {
//新建Collection对象
Collection collection=new ArrayList();
Student s1=new Student("张三",20);
Student s2=new Student("李四",22);
Student s3=new Student("王五",21);
//添加数据
collection.add(s1);
collection.add(s2);
collection.add(s3);
collection.add(s3);
System.out.println(collection.toString()); //[Student{name='张三', age=20}, Student{name='李四', age=22}, Student{name='王五', age=21}]
//删除数据
// collection.remove(s1);
// collection.clear();
//遍历
for (Object object:collection
) {
Student student=(Student)object;
System.out.println(student.toString());
}
//迭代器
Iterator iterator=collection.iterator();
while (iterator.hasNext()){
Object object= iterator.next();
System.out.println(object.toString());
}
//判断
System.out.println(collection.contains(s1));
System.out.println(collection.isEmpty());
}
}
2.List子接口
- 贴点:有序、有下标、元素可以重复
- 方法:
- void add(int index,Object o)
- boolean addAll(int index,Collection c) //将一个集合中的元素添加到此集合的index位置
- Object get (int index)
- List subList(int fromIndex,int toIndex) //返回fromIndex和toIndex之间的集合元素
public class Demo3 {
public static void main(String[] args) {
//1.创建集合对象
List list = new ArrayList();
list.add("苹果");
list.add("小米");
list.add(0,"华为");
System.out.println(list); //[华为, 苹果, 小米]
//2.删除元素
// list.remove("苹果");
// list.remove(0);
// System.out.println(list.toString());
//3.遍历
//3.1使用for
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
//3.2增强for
for (Object object:list) {
System.out.println(object);
}
//3.3使用迭代器 Iterator只有hasNext,next,remove这三个方法
Iterator iterator=list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//3.4使用列表迭代器,比Iterator强大,ListIterator可以从前往后,从后往前的增加、删除,修改
ListIterator listIterator = list.listIterator();
while (listIterator.hasNext()){
//从前往后
System.out.println(listIterator.nextIndex()+":"+listIterator.next());
}
while (listIterator.hasPrevious()){
//从后往前
System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
}
//4.判断
System.out.println(list.contains("苹果"));
//5.获取位置
System.out.println(list.indexOf("华为"));
}
}
public class Demo4 {
public static void main(String[] args) {
List list =new ArrayList();
list.add(20);
list.add(30);
list.add(40);
list.add(50);
System.out.println("元素个数"+list.size());
System.out.println(list.toString());
//2.删除操作,
//两种删除20的操作,不能直接使用list.remove(20),因为存入list中已经被封装过了
// list.remove(0);
// list.remove(new Integer(30));
// System.out.println(list.toString());
//3补充subList,返回集合,含头不含尾
System.out.println(list.subList(1,3)); //[30, 40]
}
}
3.List实现类
-
ArrayList[重点]:
- 数组结构实现,查询快、增删慢;
- JDK1.2版本,运行效率快,线程不安全。
-
Vector:
- 数组结构实现,查询快、增删慢;
- JDK1.0版本,运行效率慢、线程安全。
-
LinkedList:
- 链表结构实现,增删快,查询慢。
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// @Override
// public boolean equals(Object o) {
// if (this == o) return true;
// if (o == null || getClass() != o.getClass()) return false;
// Student student = (Student) o;
// return age == student.age &&
// Objects.equals(name, student.name);
// }
//
// @Override
// public int hashCode() {
// return Objects.hash(name, age);
// }
@Override
public boolean equals(Object obj) {
//判断是否同一个对象
if(this==obj){
return true;
}
if (obj ==null){
return false;
}
//判断是否是Student类型
if(obj instanceof Student){
Student s=(Student)obj;
//比较属性
if(this.name.equals(s.getName())&&s.age==s.getAge()){
return true;
}
}
//不满足条件返回false
return false;
}
}
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// @Override
// public boolean equals(Object o) {
// if (this == o) return true;
// if (o == null || getClass() != o.getClass()) return false;
// Student student = (Student) o;
// return age == student.age &&
// Objects.equals(name, student.name);
// }
//
// @Override
// public int hashCode() {
// return Objects.hash(name, age);
// }
@Override
public boolean equals(Object obj) {
//判断是否同一个对象
if(this==obj){
return true;
}
if (obj ==null){
return false;
}
//判断是否是Student类型
if(obj instanceof Student){
Student s=(Student)obj;
//比较属性
if(this.name.equals(s.getName())&&s.age==s.getAge()){
return true;
}
}
//不满足条件返回false
return false;
}
}
ArrayList:(用的比较多)
源码分析:DEFAULT_CAPACITY = 10;默认容量大小
注意:没有向集合中添加任何元素时,集合的容量为0,添加一个元素过后,容量为10,添加元素超过集合容量的大小时,每次扩容为1.5倍。
elementData:存放元素
size:实际元素个数
add()添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//扩容核心代码
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //扩容为1.5倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
*Vector:(用的比较少)
- 数组结构实现,查询快、增删慢;
- JDK1.0版本,运行效率慢、线程安全。
package Collection;
import java.util.Enumeration;
import java.util.Vector;
/**
* Vector集合的使用
* 存储结构:数组
* @author chengcheng
*/
public class Demo6 {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add("草莓");
vector.add("芒果");
vector.add("西瓜");
System.out.println("元素个数"+vector.size());
//2删除
// vector.remove(0);
// vector.remove("西瓜");
// vector.clear();
//3使用枚举器
Enumeration en=vector.elements();
while (en.hasMoreElements()){
Object o = en.nextElement();
System.out.println(o);
}
//4判断
System.out.println(vector.contains("西瓜"));
System.out.println(vector.isEmpty());
//vector的其他方法firstElement();astElement();elementAt();
}
}
LinkedList:
- 链表结构实现,增删快,查询慢。
package Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
/**
* LinkedList的使用
* 存储结构:双向链表
*
*/
public class Demo7 {
public static void main(String[] args) {
LinkedList linkedList=new LinkedList();
Student s1=new Student("刘德华",18);
Student s2=new Student("郭富城",19);
Student s3=new Student("梁朝伟",20);
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
System.out.println("元素个数:"+linkedList.size());
System.out.println(linkedList.toString());
//2删除
// linkedList.remove(s1);
// System.out.println(linkedList.size());
// linkedList.remove(new Student("郭富城",19));//因为在equals中重写了方法,所以能正常删除
// System.out.println(linkedList.size());
//3遍历
//for
for (int i=0; i<linkedList.size();i++){
System.out.println(linkedList.get(i));
}
//增强for
for (Object o :linkedList) {
Student s=(Student)o;
System.out.println(s.toString());
}
//迭代器
Iterator iterator=linkedList.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//ListIterator比Iterator功能更强大
ListIterator listIterator = linkedList.listIterator();
while (listIterator.hasNext()){
System.out.println(listIterator.next());
}
//逆序遍历
while (listIterator.hasPrevious()){
System.out.println(listIterator.previous());
}
//4判断
System.out.println(linkedList.contains(s1));
System.out.println(linkedList.isEmpty());
//5获取
System.out.println(linkedList.indexOf(s2));
}
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
泛型
-
Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
-
常见形式有泛型类、泛型接口、泛型方法。
-
语法:
- <T,…>T称为类型占位符,表示一种引用类型。
-
好处:
-
提高代码的重用性
-
防止类型异常转化,提高代码的安全性
*泛型类
-
package Collection;
/**
* 泛型类
* 语法:类名<T>
* T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
*/
public class MyGeneric<T> {
//使用泛型T
//1创建变量
T t;
//2泛型作为方法的参数
public void show(T t){
System.out.println(t);
}
//3泛型作为方法的返回值
public T getT(){
return t;
}
}
package Collection;
public class TestGeneric {
public static void main(String[] args) {
//使用泛型类型创建对象
//注意:1泛型只能使用引用类型,2不同泛型类型对象之间不能相互赋值
MyGeneric<String> myGeneric=new MyGeneric<>();
myGeneric.t="hello";
myGeneric.show("大家好");
System.out.println(myGeneric.getT());
MyGeneric<Integer> myGeneric1=new MyGeneric<>();
myGeneric1.t=10;
myGeneric1.show(100);
System.out.println(myGeneric1.getT());
}
}
*泛型接口
package Collection;
/**
* 泛型接口
* 语法,接口名<T>
* 注意:不能泛型静态常量
*/
public interface MyInterface<T> {
String name="张三";
T server(T t);
}
package Collection;
public class MyInterfaceImpl implements MyInterface<String> {
@Override
public String server(String s) {
System.out.println(s);
return s;
}
public static void main(String[] args) {
MyInterfaceImpl impl=new MyInterfaceImpl();
impl.server("xxx");
}
}
package Collection;
public class MyInterfaceImpl2<T> implements MyInterface<T> {
@Override
public T server(T t) {
System.out.println(t);
return t;
}
public static void main(String[] args) {
MyInterfaceImpl2<Integer> impl2=new MyInterfaceImpl2<>();
impl2.server(1000);
}
}
*泛型方法
package Collection;
/**
* 泛型方法
* 语法:<T>返回值类型
*/
public class MyGenericMethod {
//泛型方法
public <T> T show(T t){
System.out.println("泛型方法"+t);
return t;
}
public static void main(String[] args) {
MyGenericMethod myGenericMethod=new MyGenericMethod();
myGenericMethod.show("zhangsan");
myGenericMethod.show(200);
}
}
泛型集合
- 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
- 特点:
- 编译时即可检查,而非运行时抛出异常。
- 访问时,不必类型转换(拆箱)。
- 不同泛型之间引用不能相互赋值,泛型不存在多态。
package Collection;
import java.util.ArrayList;
public class Demo8 {
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("abc");
arrayList.add("bbb");
// arrayList.add(12);
for(String s:arrayList){
System.out.println(s);
}
}
}
Set子接口
-
贴点:无序、无下标、元素不可重复。
-
Set实现类:
-
HashSet(重点):
- 基于HashCode实现元素不重复。
- 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
-
TreeSet:
- 基于排列顺序实现元素不重复
-
package set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* 测试Set接口的使用
* 特点:(1)无序、没有下标(2)不能重复
*/
public class Demo1 {
public static void main(String[] args) {
//创建集合
Set<String> set=new HashSet<>();
set.add("小米");
set.add("苹果");
set.add("华为");
set.add("华为");
System.out.println("个数:"+set.size());
System.out.println(set.toString());
//删除
set.remove("华为");
//遍历,使用增强for,因为是无序的
System.out.println("---------增强for---------");
for(String s:set){
System.out.println(s);
}
//迭代器
Iterator<String> iterator=set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//判断
System.out.println( set.contains("华为"));
System.oHut.println(set.isEmpty());
}
}
HashSet案例
package set;
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet集合的使用,不重复
* 存储结构:哈希表(数组+链表+红黑树)
*/
public class Demo2 {
public static void main(String[] args) {
HashSet<String> hashSet=new HashSet<>();
hashSet.add("刘德华");
hashSet.add("梁朝伟");
hashSet.add("林志玲");
hashSet.add("周润发");
// hashSet.add("周润发");
System.out.println("元素个数:"+hashSet.size());
System.out.println(hashSet.toString());
//删除
hashSet.remove("周润发");
//遍历
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println(hashSet.contains("郭富城"));
System.out.println(hashSet.isEmpty());
}
}
案列2
package set;
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if (obj==null){
return false;
}
if(obj instanceof Person){
Person p=(Person)obj;
if (this.name.equals(p.getName())&&this.age==p.getAge()){
return true;
}
}
return false;
}
@Override
public int hashCode() {
int n1=this.name.hashCode();
int n2=this.age;
return n1+n2;
}
}
package set;
import java.util.HashSet;
/**
* HashSet集合的使用,不重复
* 存储结构:哈希表(数组+链表+红黑树)
* 存储过程(重复依据)
* (1)根据hashcode计算保存的位置,如果位置为空,则直接保存,如果不为空执行第二步。
* (2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
*/
public class Demo3 {
public static void main(String[] args) {
HashSet<Person> persons=new HashSet<>();
Person p1=new Person("刘德华",22);
Person p2=new Person("梁朝伟",23);
Person p3=new Person("郭富城",24);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(p3);//重复不能添加
persons.add(new Person("郭富城",24));//失败,因为重写了hashcode和equals
System.out.println("元素个数:"+persons.size());
System.out.println(persons.toString());
persons.remove(new Person("刘德华",22));//也能删除成功,因为重写了hashcode和equals
}
}
拓展:源码中的hascode
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
//31是一个质素,减少散列冲突(尽量存储到不同的位置)(2)31提高执行效率 31*i=(i<<5)-i 这样可以用位移
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
TreeSet:(红黑树)
- 基于排列顺序实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序。
- 元素对象的类型必须实现Comparable接口,指定排序规则。
- 通过CompareTo方法确定是否为重复元素。
例子:
package set;
import java.util.Iterator;
import java.util.TreeSet;
/**
* TreeSet的使用
* 存储结构:红黑树
*/
public class Demo4 {
public static void main(String[] args) {
TreeSet<String> treeSet=new TreeSet<>();
treeSet.add("xyz");
treeSet.add("abc");
treeSet.add("hello");
System.out.println("元素个数:"+treeSet.size());
System.out.println(treeSet.toString());
//删除
treeSet.remove("xyz");
System.out.println(treeSet.toString());
//遍历
for (String s :treeSet) {
System.out.println(s);
}
System.out.println("---------");
Iterator<String> iterator = treeSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//4判断
System.out.println(treeSet.contains("abc"));
}
}
存储对象实例:
package set;
import java.util.Objects;
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//先按姓名比,再按年龄比
@Override
public int compareTo(Person o) {
int n1=this.getName().compareTo(o.getName());
int n2=this.age-o.getAge();
return n1==0?n2:n1;
}
}
package set;
import java.util.Comparator;
import java.util.TreeSet;
/**
* 使用TreeSet保存数据
* 存储结构:红黑树
* 要求:元素必须要实现Comparable接口,compareTo()方法返回值0,认为是重复元素
*/
public class Demo5 {
public static void main(String[] args) {
TreeSet<Person> persons=new TreeSet<>();
Person p1=new Person("刘德华",22);
Person p2=new Person("梁朝伟",23);
Person p3=new Person("郭富城",24);
Person p4=new Person("郭富城",20);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(p4);
System.out.println("元素个数:"+persons.size());
//
persons.remove(new Person("刘德华",22));//比的是姓名和年龄,所以能删除。不要搞混淆与equals和hashcode.
System.out.println(persons.size());
}
}
拓展:
package set;
import java.util.Comparator;
import java.util.TreeSet;
/**
* TreeSet集合的使用
* comparator:实现定制比较(比较器)
* comparable:可比较的
*/
public class Demo6 {
public static void main(String[] args) {
//创建集合,并指定比较规则,这样在写Person类时可以不不用实现Comparable接口
TreeSet<Person> persons=new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1=o1.getAge()-o2.getAge();
int n2=o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
Person p1=new Person("刘德华",22);
Person p2=new Person("梁朝伟",23);
Person p3=new Person("郭富城",24);
Person p4=new Person("郭富城",20);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(p4);
System.out.println(persons);
}
}
拓展2:
package set;
import java.util.Comparator;
import java.util.TreeSet;
/**
* 要求,使用TreeSet集合实现字符串按照长度进行排序,默认按照字母顺序排序
* helloworld zhang lisi wangwu beijing xian nanjing
* Comparator接口实现定制比较
*/
public class Demo7 {
public static void main(String[] args) {
TreeSet<String> treeSet=new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1=o1.length()-o2.length();
int n2=o1.compareTo(o2);
return n1==0?n2:n1;
}
});
treeSet.add("helloworld");
treeSet.add("pingguo");
treeSet.add("lisi");
treeSet.add("zhangsan");
treeSet.add("beijing");
treeSet.add("cat");
treeSet.add("nanjing");
treeSet.add("xian");
System.out.println(treeSet);//[cat, lisi, xian, beijing, nanjing, pingguo, zhangsan, helloworld]
}
}
Map集合
Map父接口
- 特点:存储一对数据(Key-Value),无序,无下标,键不可重复,值可重复。
- 方法:
- V put(K key,V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
- Object get(Object key) //根据键获取对应的值。
- keySet //返回所有key。
- Collection value() //返回包含所有值的Collection集合。
- entrySet<Map.Entry<K,V>> //键值匹配的Set集合。
package map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Map接口的使用
* 特点:(1)存储键值对(2)键不能重复,值可以重复(3)无序
*/
public class Demo1 {
public static void main(String[] args) {
//创建Map集合
Map<String,String > map=new HashMap<>();
map.put("cn","中国");
map.put("uk","英国");
map.put("usa","美国");
map.put("cn","zhongguo"); //key重复,会覆盖之前的
System.out.println(map.toString());
//删除
map.remove("usa");
//遍历
//使用keySet();
// Set<String> keySet = map.keySet();
for (String key:map.keySet()){
System.out.println(key+"---------"+map.get(key));
}
//使用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("泰国"));
}
}
Map集合的实现类:
hashMap(重点):
JDK1.2版本,线程不安全,运行效率快;允许null 作为key或是value.
构造方法hashMap() 构造一个具有默认初始容量(16)和默认加载因子(0.75)的空HashMap.
实例:
package map;
import java.util.Objects;
public class Student {
private String name;
private int stuNo;
public Student() {
}
public Student(String name, int stuNo) {
this.name = name;
this.stuNo = stuNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuNo() {
return stuNo;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", stuNo=" + stuNo +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return stuNo == student.stuNo &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, stuNo);
}
}
package map;
import java.util.HashMap;
import java.util.Map;
/**
* HashMap集合的使用
* 存储结构:哈希表(数组+链表+红黑树)
* 使用key的hashcode和equals作为重复
* @author chengcheng
*/
public class Demo2 {
public static void main(String[] args) {
//创建集合K,V
HashMap<Student,String> students=new HashMap<Student,String>();
//添加元素
Student s1=new Student("孙悟空",100);
Student s2=new Student("猪八戒",101);
Student s3=new Student("沙和尚",102);
Student s4=new Student("唐生",103);
students.put(s1,"北京");
students.put(s2,"上海");
students.put(s3,"杭州");
students.put(s4,"重庆");
students.put(new Student("孙悟空",100),"北京");
System.out.println(students.size());
System.out.println(students.toString());
//删除
students.remove(s1);
//使用keySet();
for(Student key:students.keySet()){
System.out.println(key.toString()+"------------"+students.get(key));
}
//entrySet()
System.out.println("----------entrySet-----------------");
for(Map.Entry<Student,String> entry:students.entrySet()){
System.out.println(entry.getKey()+"------"+entry.getValue());
}
//判断
System.out.println(students.containsKey(s2));
}
}
源码:
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 //数组初始长度
static final int MAXIMUM_CAPACITY = 1 << 30; //数组最大长度
static final float DEFAULT_LOAD_FACTOR = 0.75f; //默认加载因子
static final int TREEIFY_THRESHOLD = 8; //JDK1.8链表最大长度,超过8且数组长度大圩等于64会变成红黑树,这样会提高查询效率
static final int UNTREEIFY_THRESHOLD = 6; //JDK1.8链表长度小于6时,调整成链表
static final int MIN_TREEIFY_CAPACITY = 64;
transient Node<K,V>[] table;//哈希表中的数组
transient int size;//元素个数
//hashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
//JDK1.8以前,链表是头插入,JDK1.8以后是为插入
实际上HashSet里面使用了HashMap来存储
-
Hashtable:(用的不多了)
- JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value
-
Properties:
- Hashtable的子类,要求key和value都是String.通常用于配置文件的读取。
-
TreeMap:
- 实现了SortedMap接口(是Map的子接口),可以对key自动排序。
实例:
package map;
import java.util.Objects;
public class Student implements Comparable<Student> {
private String name;
private int stuNo;
public Student() {
}
public Student(String name, int stuNo) {
this.name = name;
this.stuNo = stuNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuNo() {
return stuNo;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", stuNo=" + stuNo +
'}';
}
@Override
public int compareTo(Student o) {
int n2=this.stuNo-o.getStuNo();
return n2;
}
}
package map;
import java.util.Map;
import java.util.TreeMap;
/**
* TreeMap的使用
* 存储结构:红黑树
* @author chengcheng
*/
public class Demo3 {
public static void main(String[] args) {
//新建集合
TreeMap<Student,String> students=new TreeMap<>();
//添加元素
Student s1=new Student("孙悟空",100);
Student s2=new Student("猪八戒",101);
Student s3=new Student("沙和尚",102);
Student s4=new Student("唐生",103);
students.put(s1,"北京");
students.put(s2,"上海");
students.put(s3,"杭州");
students.put(s4,"重庆");
students.put(new Student("孙悟空",100),"北京1"); //也能添加
System.out.println(students.size());
System.out.println(students.toString());
//删除
students.remove(s1);
students.remove(new Student("唐生",103));//也能删除
System.out.println(students.size());
//遍历
for(Student key:students.keySet()){
System.out.println(key+"=========="+students.get(key));
}
for (Map.Entry<Student,String> entry:students.entrySet()){
System.out.println(entry.getKey()+"=========="+entry.getValue());
}
//判断
System.out.println(students.containsKey(new Student("沙和尚",102)));
}
}
Exception in thread “main” java.lang.ClassCastException: map.Student cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at map.Demo3.main(Demo3.java:19)
这种错误注意:要实现 Comparable<>接口
Colletions工具类
- 概念:集合工具类,定义了除了存取以外的集合常用方法。
- 方法:
- public static void reverse(List<?> list) //反转集合找那个元素的顺序
- public static void shuffle(List<?> list) //随机重置结合元素的顺序
- public static void sort(List list) //升序排序(元素类型必须实现Comparable接口)
package map;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 演示Collections工具类的使用
*/
public class Demo4 {
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();
list.add(200);
list.add(300);
list.add(6);
list.add(580);
list.add(23);
//sort排序
System.out.println("排序之前:"+list.toString());
Collections.sort(list);
System.out.println("排序之后:"+list.toString());
//binarySearch 二分查找
int i = Collections.binarySearch(list, 6);
System.out.println(i);
//copy复制
// List<Integer> dest=new ArrayList<>(); //这样创建出来大小为0
// Collections.copy(dest,list);
// System.out.println(dest); //Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest
List<Integer> dest=new ArrayList<>();
for(int k=0;k<list.size();k++){
dest.add(0);
}
Collections.copy(dest,list);
System.out.println(dest);
//reverse反转
Collections.reverse(list);
System.out.println("反转之后"+list);
//shuffle打乱
Collections.shuffle(list);
System.out.println("打乱之后:"+list);
//补充:list转化成数组
System.out.println("----------list转数组------------");
Integer[] integers = list.toArray(new Integer[0]);
System.out.println(integers.length);
System.out.println(Arrays.toString(integers));
//数组变集合
String[] names={"zhangshan","lisi","wangwu "};
//集合是受限集合,不能添加和删除
List<String> lists = Arrays.asList(names);
// lists.add("zhaoliu"); 会报错
// lists.remove("lisi"); 会报错
System.out.println(lists);
// int[] nums={100,300,399};
// List<int[]> ints = Arrays.asList(nums);
// for (int[] s:ints){
// System.out.println(Arrays.toString(s));
// }
//注意:把基本类型数组转化成集合时,需要修改为包装类型
Integer[] nums={100,300,399};
List<Integer> list1 = Arrays.asList(nums);
System.out.println(list1);
}
}
集合总结:
- 集合的概念:
- 对象的容器,和数组类似,定义了对多个对象进行操作的常用方法。
- List集合:
- 有序、有下标、元素可以重复。(ArrayList、LinkedList、Vector)
- Set集合:
- 无序、无下标、元素不可重复。(HashSet、TreeSet)
- Map集合:
- 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
- Collections:
- 集合工具类,定义了除了存取以外的集合常用方法。