集合是Java中提供的一种容器,可以用来存储多个数据。
数组:存储一组相同类型的数据结构
局限:定长
集合:动态存放多个对象。
动态:集合的大小随着存储的数据量而改变。
多个:0~多个数据
对象:存储类的实例。基本数据类型—>包装类对象。
集合框架[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7MW7do0N-1633501776094)(C:Users24329Desktop集合框架.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dGCS1XOj-1633501776096)(C:Users24329Desktop屏幕截图 2021-10-01 173105.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-exYThUji-1633501776097)(C:Users24329Desktop2.png)]
Collection常用功能| 方法 | 描述 |
|---|---|
| boolean add(Object obj) | 添加一个对象数据 |
| boolean addAll(Collection c) | 将一个集合中的所有对象添加到此集合中 |
| void clear() | 清空此集合中的所有对象 |
| boolean contains(Object obj) | 检查此集合中是否包含obj对象 |
| boolean equals(Object obj) | 比较此集合中是否与指定对象相等 |
| boolean isEmpty() | 判断此集合中是否为空 |
| boolean remove(Object obj) | 在此集合中移除obj对象 |
| int size() | 返回此集合中的元素个数 |
| Object[] toArray() | 将此集合转换成数组 |
示例:
class Person{}
public class CollectionDemo {
public static void main(String[] args) {
//1.创建对象
Collection con = new ArrayList();
//添加元素
con.add(123);//向上转型,int...>Integer...>Object
con.add(true);
con.add("hello");
con.add(new Person());
Collection subCol = new ArrayList();
subCol.add(1);
subCol.add(2);
System.out.println("subCol:"+ subCol);
con.add(subCol);//添加一个集合
System.out.println("con:"+con);
//清空
// con.clear();
System.out.println("清空之后得到con:"+con);
//是否包含某个元素
boolean contains = con.contains("hello");
System.out.println("是否包含contains:"+contains);
//equals
Collection collection = new ArrayList();
collection.add("1");
collection.add("2");
System.out.println("collection:"+ collection);
boolean equals = subCol.equals(collection);//比较的是内容
System.out.println("两个集合是否equals:"+ equals);
// con.clear();
// System.out.println("是否为空:"+con.isEmpty());
//删除某个元素
con.remove("1");
System.out.println("删除元素之后:"+ con);
System.out.println("集合里面有多少个元素:"+ con.size());
//集合转数组
Object[] objects = con.toArray();
System.out.println("集合转数组:"+ Arrays.toString(objects));
}
}
Iterator迭代器
在程序开发中,经常需要遍历集合中的所有元素。
迭代:即Collection集合元素的通用获取手段,在获取元素之前需要先判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有旧在取出来,一直把集合中的所有元素全部取出,这种取出的方式专业术语上称为迭代。
Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素。而Iterator主要用于迭代访问(即遍历)Collection中的元素。因此Iterator对象也被称为迭代器。
迭代器的常用方法
public Iterator iterator(); //获取集合对应的迭代器,用来遍历集合中的元素。 Iterator接口的常用方法 public E next(); //返回迭代的下一个元素 public boolean hasNext(); //如果仍有元素可以迭代,则返回true step1:先获取集合上的迭代器 Iterator it = c1.iterator(); step2:先判断迭代器后是否有数据 it.hasNext()-->boolean step3:通过迭代器获取集合的元素 it.next()-->E
示例:
public class CollectionDemo2 {
public static void main(String[] args) {
//1.创建对象
Collection col = new ArrayList();//可变长度
//添加元素
col.add(123); //向上转型,int-->Integer-->Object
col.add(true);
col.add("hello");
//集合的遍历 for
// for (int i = 0; i < col.size(); i++) {
// //Collection这个父接口没有与下标相关的方法 所以不用fori循环
// }
//foreach
// for (Object o : col) {
// System.out.println(o);
// }
//迭代器 简化
Iterator iterator = col.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println("obj:"+obj);
//不要在迭代的过程中删除元素
//col.remove("hello"); //java.util.ConcurrentModificationException
//需要这样用迭代器删除
iterator.remove();
}
System.out.println("col:"+col);
// //迭代器
// Iterator iterator = col.iterator();
// boolean b = iterator.hasNext();
// if (b) {
// Object obj = iterator.next();
// System.out.println("obj:"+obj);
// }
//
// b = iterator.hasNext();
// if (b) {
// Object obj = iterator.next();
// System.out.println("obj:"+obj);
// }
//
// b = iterator.hasNext();
// if (b) {
// Object obj = iterator.next();
// System.out.println("obj:"+obj);
// }
//
// //当判断到第四个元素是否存在的时候,会返回false
b = iterator.hasNext();
if (b) {
Object obj = iterator.next();
System.out.println("obj:"+obj);
}
// Object next = iterator.next(); //java.util.NoSuchElementException
// System.out.println("next:"+next);
}
}
2.泛型
概念
集合可以任意存放对象,只要把对象存储集合后,那么这时他们会被提升成Object类型,当我们再取出每一个对象,并且进行相应的操作,这时候就必须采用类型转换。
没有泛型的话,取出来的话,需要向下转型,效率低下,容易产生错误。
泛型:保护数据类型的安全。
语法:
Collection<数据类型> 对象 = new ArrayList();
示例:
Collection泛型的定义 定义含有泛型的类c = new ArrayList(); c.add("hello"); c.add("world"); //c.add(123); System.out.println(c);
定义格式:
修饰符 class 类名<代表泛型的变量>{}
什么时候确定泛型?在创建对象的时候确定泛型
示例:
//定义带有泛型的类 public class Point定义含有泛型的方法{ private T x; private T y; //在方法上定义含有泛型的方法 public static void getValue(K k){ System.out.println("k:"+k); } //在方法上定义含有泛型的方法 public static void test(M m){ // System.out.println("检测到了静态方法上的泛型:"+ m); } public T getX() { return x; } public void setX(T x) { this.x = x; } public T getY() { return y; } public void setY(T y) { this.y = y; } } public class PointTest { public static void main(String[] args) { //创建对象的时候确定泛型的类型 Point point = new Point<>(); point.setX(34); point.setY(123); System.out.println("---------------"); Point point2 = new Point<>(); point2.setX("长34"); point2.setY("宽12"); //定义在方法的泛型,在调用时才确定类型 Point.test("wowo"); point.test(23); Point.getValue(67); Point.getValue("zhangsan"); } }
定义格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){}
什么时候确定泛型?调用方法时,确定泛型的类型
示例:
//在方法上定义含有泛型的方法
public static void getValue(K k){
System.out.println("k:"+k);
}
//在方法上定义含有泛型的方法
public static void test(M m){
System.out.println("检测到了静态方法上的泛型:"+ m);
}
//定义在方法的泛型,在调用时才确定类型
Point.test("wowo");
point.test(23);
Point.getValue(67);
Point.getValue("zhangsan");
含有泛型的接口定义格式:
修饰符 interface 接口名<代表泛型的变量> {}
示例:
public interface Door泛型通配符{ public T getType(); } class DoorImpl implements Door { @Override public String getType() { return null; } } class DoorImpl2 implements Door { @Override public Integer getType() { return null; } }
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以,可以通过通配符>表示。但是一旦使用了泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
?:通配符,不确定类型,代表集合中可以存储任意类型的数据。
List :该容器有数据类型Object。
? extends E 确定了上限,集合的泛型,E以及E的子类
? super E 确定了下限,集合泛型,E以及E的父类
示例:
class Person{}
class Student extends Person{}
public class Demo3 {
//代表可以接受任意类型
public static void test1(List> list) {
}
//代表可以接受任意类型
public static void test2(List
3.集合
List接口
特点:有序,有下标。元素可以重复。
List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且增加了一些根据元素索引来操作集合的特有方法。如下:
| public void add(int index,E element); | 将指定的元素,添加到该集合中的指定位置上 |
|---|---|
| public E get(int indedx) | 返回集合中指定位置的元素 |
| public E remove(int index) | 移除列表中指定位置的元素,返回的是被移除的元素 |
| public E set(int index,E element) | 用指定元素替换集合中指定位置的元素,返回值的 更新向前的元素 |
java.util.ArrayList 集合数据存储的结构是数组结构。元素增删慢,查找快。
优点:查询数据,遍历数据效率很高。它使用索引快速定位对象
缺点:ArrayList在添加和删除元素的时候比linkedList比较慢。因为用了数组,需要移动后面的元素以调整索引的顺序。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c2h2KV2X-1633501776099)(C:Users24329DesktopArrayList.png)]
示例:
public class ListDemo {
public static void main(String[] args) {
//创建对象
ArrayList list = new ArrayList<>();
//添加元素
list.add(0,100);
list.add(1,200);
list.add(2,300);
list.add(3,400);
System.out.println("list:"+list);
//获取元素
Integer element = list.get(2);
System.out.println("element:"+element);
//修改
list.set(2,999);
System.out.println("修改后的集合:"+list);
//删除
list.remove(3);
System.out.println("删除后的集合:"+list);
}
}
linkedList
java.util.linkedList 集合数据存储的结构是链表结构,方便元素添加,删除的集合,访问遍历相对于ArrayList较慢。
数据结构:链表
特点:查询慢,链表中地址不是连续的,每次查询元素,必须从头开始。
增删快,链表结构,增加删除一个元素,对链表整体的结构没有影响。所以增删快。
集合的添加与删除经常涉及到的首尾操作,而linkedList提供了大量的首尾操作方法。
如下:
| public void addFirst(E e) | 将指定元素插入此列表的开头 |
|---|---|
| public void addLast(E e) | 将制定元素添加到此列表的结尾 |
| public E getFirst() | 返回列表的第一个元素 |
| public E getLast() | 返回列表的最后一个元素 |
| public E removeFirst() | 移除并返回此列表的第一个元素 |
| public E removeLast() | 移除并返回此列表的最后一个元素 |
| public E pop() | 从此列表所表示的堆栈处弹出一个元素 |
| public void push(E e) | 将元素推入此列表所表示的堆栈 |
| public boolean isEmpty() | 如果列表不包含元素,则返回true |
示例:
public class linkedListDemo {
public static void main(String[] args) {
linkedList list = new linkedList<>();
list.addFirst("123");
list.addFirst("234");
list.addFirst("hello");
list.addFirst("true");
System.out.println("list:"+list);
System.out.println("---------------------");
System.out.println("弹出一个元素:"+ list.pop());
System.out.println("弹出一个元素之后打印:"+ list);
}
}
Set接口
特点:无序,无下标,元素不可重复。
方法:全部继承自Collection中的方法。
使用foreach循环遍历:for(数据类型 局部变量 : 集合名){ //循环内部的局部变量,代表当次循环从集合中去处的对象}
Set实现类 HashSet特点:无序,去重
JDK提供的类中,String,Integer可以直接添加到HashSet,自动去重。
自定义类:自己重写hashCode()和equals(),必须同时重写。
示例:
class Cat{
private String name;
private int 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 "Cat{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public Cat() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cat cat = (Cat) o;
return age == cat.age &&
name.equals(cat.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class SetDemo {
public static void main(String[] args) {
Set set = new HashSet<>();
//添加
set.add("hello1");
set.add("hello2");
set.add("hello3");
set.add("hello4");
System.out.println(set);
System.out.println("-------------------");
//遍历
for (String s : set) {
System.out.println("s:"+s);
}
System.out.println("---------------");
//迭代器
Iterator iterator = set.iterator();
while(iterator.hasNext()){
String next = iterator.next();
System.out.println("next:"+next);
}
System.out.println("----------------");
Set set2 = new HashSet<>();
//添加
set2.add(2);
set2.add(3);
set2.add(4);
set2.add(5);
System.out.println("set2:"+set2);
System.out.println("-------------------");
//自定义类型 如果希望自定义类型的成员相同的时候,不要重复添加到set集合,那么应该重写hashCode()和equals()方法
Set catSet = new HashSet<>();
catSet.add(new Cat("Cat1",1));
catSet.add(new Cat("Cat2",2));
catSet.add(new Cat("Cat3",3));
System.out.println("catSet:"+catSet);
}
}
TreeSet
特点:有序,去重
JDK提供的类String、Integer。已经实现了这个Comparable接口,自动有序去重;
自定义的类:实现Comparable接口的comparableTo方法,在这个方法里重写相应的排序的规则。
示例:
public class Dog implements Comparable{ private String name; private int age; //比较的方法 (从大到小) @Override public int compareTo(Dog dog) { //this指向新增加进来的元素 if (this.getAge() > dog.getAge()){ return -1; }else if (this.getAge() < dog.getAge()){ return 1; } //如果年龄相等,在比较名字。 return this.getName().compareTo(dog.getName()); } @Override public String toString() { return "Dog{" + "name='" + name + ''' + ", age=" + age + '}'; } public Dog() {} public Dog(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Dog dog = (Dog) o; return age == dog.age && Objects.equals(name, dog.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; } } public class TreeSetDemo { public static void main(String[] args) { TreeSet set = new TreeSet<>(); set.add("aaa"); set.add("bbb"); set.add("ddd"); set.add("ccc"); System.out.println("set:"+set); System.out.println("------------------"); TreeSet set2 = new TreeSet<>(); set2.add(111); set2.add(222); set2.add(1); set2.add(2); set2.add(3); System.out.println("set2:"+set2); System.out.println("-----------------"); Set dogSet = new TreeSet<>(); dogSet.add(new Dog("小狗1",1)); dogSet.add(new Dog("小狗2",2)); //添加第二个元素的时候 dogSet.add(new Dog("小狗3",3)); dogSet.add(new Dog("小狗4",3)); //去重 System.out.println("dogSet:"+dogSet); } }
Comparator接口
比较器,实现定制比较。
compare(o1,o2)方法的返回值0,表示重复。
示例:
public class TestComparator {
public static void main(String[] args) {
//创建集合的时候,并指定比较器规则
TreeSet dogTreeSet = new TreeSet<>(new Comparator() {
@Override
public int compare(Dog dog1, Dog dog2) {
if (dog1.getAge()>dog2.getAge()) {
return 1;
}else if (dog1.getAge() < dog2.getAge()) {
return -1;
}
return dog1.getName().compareTo(dog2.getName());
// return 0;
}
});
dogTreeSet.add(new Dog("小狗1",1));
dogTreeSet.add(new Dog("小狗2",2)); //添加第二个元素的时候
dogTreeSet.add(new Dog("小狗3",3));
dogTreeSet.add(new Dog("小狗4",3)); //去重
System.out.println("dogTreeSet:"+dogTreeSet);
}
}
Map接口
map接口,也是一种容器,存储的数据是成双成对儿出现的。键(key)、值(value)。
map存储的是键值对:key-value
注意点:
1、存储无序的键值对儿
2、key必须是唯一的,而且和value是一一对应的。
常用的方法:
| 方法名 | 描述 |
|---|---|
| V put(K key, V Value) | 将对象存入到集合中,关联键值。key重复则覆盖原值 |
| Object get(Object key) | 根据键获取对应的值 |
| Set keySet() | 返回所有的key |
| Collection values() | 返回包含所有值的collection集合 |
| Set | 键值匹配的Set集合 |
JDK1.2版本,线程不安全,运行效率快。
允许用null作为key或是value。
存储结构:哈希表。
示例:
public class MapDemo {
public static void main(String[] args) {
Map map = new HashMap<>();
//put(key,value); 添加元素:key要唯一
map.put("台湾1","周杰伦1");
map.put("台湾2","周杰伦2");
map.put("台湾3","周杰伦3");
System.out.println(map);
System.out.println("------------------");
//如果有重复的key值,那么会覆盖原来的value值
map.put("台湾1","周杰伦4");
System.out.println(map);
System.out.println("------------------");
//根据key获取对应的value值
System.out.println("map.get("台湾2"):"+map.get("台湾2"));
System.out.println("------------------");
//是否包含
boolean result = map.containsKey("台湾1");
System.out.println("是否包含这个key值:"+ result);
System.out.println("------------------");
//删除元素 remove(key);
map.remove("台湾3");
System.out.println("删除之后的map:"+map);
System.out.println("------------------");
//遍历 map.keySet();
Set keySet = map.keySet();
for (String key : keySet) {
String value = map.get(key);
System.out.println("value:"+value);
}
System.out.println("------------------");
//遍历2 map.entrySet();
Set> entrySet = map.entrySet();
for (Map.Entry set : entrySet) {
System.out.println(set.getKey()+":"+set.getValue());
}
HashMap hashMap = new HashMap<>();
hashMap.put("aaa",1);
hashMap.put("ddd",2);
hashMap.put("ccc",1);
hashMap.put("bb",4);
System.out.println("hashMap:"+hashMap);
}
}
TreeMap
实现了SortedMap接口(Map的子接口),可以对key自动排序。Key需实现Comparable接口。
public class TreeMapDemo {
public static void main(String[] args) {
//key会自动排序,要实现comparable接口
TreeMap treeMap = new TreeMap<>();
treeMap.put("bbb",2);
treeMap.put("aaa",1);
treeMap.put("ddd",4);
treeMap.put("ccc",3);
System.out.println("treeMap:"+treeMap);
}
}
4.Collections工具类
常用方法:
| 方法 | 描述 |
|---|---|
| public static void reverse(List> list) | 反转集合中元素的顺序 |
| public static void shuffle(List> list) | 随机重置集合元素的顺序 |
| public static void sort(List> list) | 升序排序(元素类型必须实现Comparable接口) |
| public static int binarySearch(list,T key) | 二分查找 |
示例:
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("aaa");
list.add("333");
list.add("222");
list.add("111");
System.out.println("排序前的:"+list);
//Collection工具类的常用方法
Collections.addAll(list,"hello","world");
System.out.println(list);
//排序
Collections.sort(list);
System.out.println("排序后的:"+list);
//搜索
int index = Collections.binarySearch(list,"111");
System.out.println("index:"+index);
//反转
Collections.reverse(list);
System.out.println("反转之后的list:"+list);
}
}
|
| public static void sort(List> list) | 升序排序(元素类型必须实现Comparable接口) |
| public static int binarySearch(list,T key) | 二分查找 |
示例:
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("aaa");
list.add("333");
list.add("222");
list.add("111");
System.out.println("排序前的:"+list);
//Collection工具类的常用方法
Collections.addAll(list,"hello","world");
System.out.println(list);
//排序
Collections.sort(list);
System.out.println("排序后的:"+list);
//搜索
int index = Collections.binarySearch(list,"111");
System.out.println("index:"+index);
//反转
Collections.reverse(list);
System.out.println("反转之后的list:"+list);
}
}



