一、Collection集合
集合的概念概念:集合是java中提供的一种容器 ,可以用来存储多个数据。数组 :存储一组相同数据类型的数据结构。 局限:定长集合 :动态存放多个对象。 动态:集合的大小随着存储的数据量而改变。 多个:0-多个数据 对象:存储类的实例。基本数据类型—->包装类对象。
集合框架
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()
将此集合转换成数组
示例1:package com . alpaak . part8 ; import java . util . ArrayList ; import java . util . Collection ; /** Collection 常用功能 */ public class Demo1_Collection { public static void main ( String [] args ) { //step1:创建一个容器 Collection collection1 = new ArrayList (); System . out . println ( "集合的样子:" + collection1 ); //step2:往容器中添加元素 boolean flag = collection1 . add ( "abc" ); //返回一个boolean值,判断是否添加成功 System . out . println ( "add操作flag:" + flag ); //System.out.println(collection1); collection1 . add ( true ); collection1 . add ( 123 ); //---->int---->Integer---->Object System . out . println ( "添加后:" + collection1 ); //重写了toString()方法 System . out . println ( "集合的元素个数:" + collection1 . size ()); System . out . println ( "-----------------" ); Collection c2 = new ArrayList (); c2 . add ( 12 ); c2 . add ( 45 ); c2 . add ( 67 ); collection1 . addAll ( c2 ); System . out . println ( "将集合中元素一次性添加到目标集合中" + collection1 ); System . out . println ( "---------" ); System . out . println ( collection1 . contains ( "abc" )); System . out . println ( collection1 . containsAll ( c2 )); //判断是否包含集合c2中所有的元素 System . out . println ( "-------------" ); System . out . println ( collection1 . isEmpty ()); //判断集合是否为空 System . out . println ( "------------" ); collection1 . remove ( true ); //删除集合中的一个元素 System . out . println ( "remove删除操作后: " + collection1 ); collection1 . removeAll ( c2 ); //删除指定的集合中所有的元素 System . out . println ( "removeAll删除操作后: " + collection1 ); System . out . println ( "--------------" ); collection1 . clear (); System . out . println ( "清空后的集合: " + collection1 ); System . out . println ( "------------" ); Collection c3 = new ArrayList (); c3 . add ( 123 ); c3 . add ( 345 ); collection1 . add ( 123 ); collection1 . add ( true ); collection1 . add ( "abc" ); System . out . println ( "集合1:" + collection1 ); System . out . println ( "集合3:" + c3 ); collection1 . retainAll ( c3 ); //交集:仅保留此集合中包含在指定集合中的元素 System . out . println ( "集合1通过retainAll交集操作后: " + collection1 ); } }
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
示例2:package com . alpaak . part8 ; import java . util . ArrayList ; import java . util . Collection ; import java . util . Iterator ; /** Iterator迭代器 */ public class Demo2_Iterator { public static void main ( String [] args ) { Collection < String > c1 = new ArrayList <>(); c1 . add ( "aa" ); c1 . add ( "bb" ); c1 . add ( "cc" ); c1 . add ( "dd" ); //3.2使用迭代器(迭代器专门用来遍历集合的一种方式) //hasNext();有没有下一个元素, //next();获取下一个元素 //remove();删除当前元素 Iterator < String > iterator = c1 . iterator (); if ( iterator . hasNext ()){ System . out . println ( iterator . next ()); //不能使用collection删除方法,因为遍历同时不能使用集合删除方法,否则出现并发修改异常。 //可以使用迭代器的删除方法 //c1.remove(s); //iterator.remove(); } System . out . println ( iterator . next ()); System . out . println ( iterator . next ()); System . out . println ( iterator . next ()); System . out . println ( iterator . next ()); System . out . println ( iterator . next ()); //java.util.NoSuchElementException } }
概念我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。 没有泛型的话,取出来的话,需要向下转型,效率低下。容易产生错误。 泛型:保护数据类型的安全。 语法:
Collection <数据类型> c1 = new ArrayList (); //JDK1.7版本之后
示例
Collection < String > c1 = new ArrayList (); //jdk1.7版本之后,后面不用再声明<String> c1 . add ( "hello" ); c1 . add ( "world" ); //c1.add(123); System . out . println ( c1 );
泛型的定义
定义含有泛型的类定义格式:
修饰符 class 类名<代表泛型的变量> { }
什么时候确定泛型?在创建对象的时候确定泛型
定义含有泛型的方法定义格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
什么时候确定泛型?调用方法时,确定泛型的类型
示例3:package com . alpaak . part8 ; //作用在类上的泛型:当数据类型不确定的时候,可以一个泛型,通过创建对象传递过来一个类型,来确定T的类型 class Point < T >{ private T x ; private T y ; public static < M > 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 Demo3_Paradigm { public static void main ( String [] args ) { Point < String > point = new Point <>(); point . setX ( "wowow" ); point . setY ( "wowow" ); Point < Integer > point4 = new Point <>(); point4 . setY ( 2 ); point4 . setX ( 3 ); Point . test ( "wowo" ); Point . test ( 23 ); } }
含有泛型的接口定义格式:
修饰符 interface 接口名<代表泛型的变量> { }
示例4package com . alpaak . part8 . demo4 ; /** * 接口上声明泛型 * @param <T1> * @param <T2> */ public interface A < T1 , T2 > { void test1 ( T1 t1 ); void test2 ( T2 t2 ); }
package com . alpaak . part8 . demo4 ; //实现类使用 public class AImpl implements A < String , Integer > { @Override public void test1 ( String s ) { } @Override public void test2 ( Integer integer ) { } }
泛型通配符 当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。 ?:通配符,不确定类型,代表集合中可以存储任意类型的数据。 List:该容器有数据类型:Object List<?>:该容器的数据类型可以是任意的
? extends E 限定了上限,集合的泛型: E 以及 E 的子类
? super E 限定了下限,集合泛型: E 以及 E 的父类
示例5:package com . alpaak . part8 . demo5 ; import java . util . ArrayList ; import java . util . List ; class Person {} class Student extends Person {} /** * 泛型通配符 */ public class Demo5 { //?代表可以接收任意类型 public static void test1 ( List <?> list ){ } public static void test2 ( List < Object > list ){ } //? extends Person限定所有类型是Person以及Person的子类, public static void test3 ( List <? extends Person > list ){} //? super Student限定所有类型是Student以及Student的父类 public static void test4 ( List <? super Student > list ){} public static void main ( String [] args ) { List < String > list1 = new ArrayList < String >(); List < Integer > list2 = new ArrayList <>(); test1 ( list2 ); List < Object > list3 = new ArrayList <>(); list3 . add ( 1 ); list3 . add ( "wowo" ); test2 ( list3 ); List < Person > list4 = new ArrayList <>(); List < Student > list5 = new ArrayList <>(); test3 ( list4 ); test4 ( list4 ); } }
三、集合
List接口特点:有序、有下标、元素可以重复。 List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操 作集合的特有方法,如下: public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。 public E get(int index) :返回集合中指定位置的元素。 public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。 public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。List集合特有的方法都是跟索引相关
List实现类
ArrayListjava.util.ArrayList 集合数据存储的结构是数组结构 。元素增删慢,查找快,由于日常开发中使用最多的功能为 查询数据、遍历数据,所以 ArrayList 是最常用的集合。 优点:查询数据、遍历数据效率很高。它使用索引快速定位对象。 缺点:是插入或删除元素相对于LinkedList较慢。因为用了数组,需要移动后面的元素以调整索引的顺序。
示例6:package com.alpaak.part8;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* ArrayList类的使用
*/
public class Demo6_ArrayList {
public static void main(String[] args) {
List<String> list = new ArrayList();
list.add("wowo");
list.add("aa");
list.add("dd");
System.out.println(list);
list.add(1,"cc");//在指定的下标添加元素
System.out.println(list);
String ele = list.get(1);//获取指定下标的元素;
System.out.println("ele:"+ele);
int index = list.indexOf("ada");//返回元素所在的下标;
System.out.println("index:"+index);
String remove = list.remove(2);//删除指定下标的元素
System.out.println("remove:"+remove);
System.out.println(list);
boolean flag = list.remove("ads");
System.out.println("flag:"+flag);
System.out.println(list);
list.set(1,"XXXX");//设置指定下标的元素
System.out.println(list);
list.add("hello");
list.add("wowo");
System.out.println(list);
List sublist = list.subList(2,4);//返回一个指定下标范围之间的子集
System.out.println(sublist);
Object[] objects = list.toArray();
System.out.println(Arrays.toString(objects));
}
}
LinkedListjava.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。
示例7:package com.alpaak.part8;
import java.util.LinkedList;
/**
* LinkedList使用
*/
public class Demo7_LinkedList {
public static void main(String[] args) {
LinkedList<String> link = new LinkedList<>();
//添加元素
link.addFirst("abc1");
link.addFirst("abc2");
link.addFirst("abc3");
System.out.println(link);
// 获取元素
System.out.println(link.getFirst());
System.out.println(link.getLast());
// 删除元素
System.out.println(link.removeFirst());
System.out.println(link.removeLast());
while (!link.isEmpty()) {//判断集合是否为空
System.out.println(link.pop());//弹出集合中的栈顶元素
}
System.out.println(link);
}
}
Set接口特点:无序、无下标、元素不可重复。 方法:全部继承自Collection中的方法。 使用foreach循环遍历: for(数据类型 局部变量 : 集合名){ //循环内部的局部变量,代表当次循环从集合中取出的对象 }
Set实现类
HashSet特点:无序,去重 JDK提供的类:String,Integer可以直接添加到HashSet,自动去重; 自定义类:自己重写hashCode()和equals(),必须同时重写。
示例8自定义类
package com.alpaak.part8.demo8;
import java.util.Objects;
public class Person implements Comparable<Person> {
private String name;
private int age;
@Override
public int compareTo(Person o) {
if(age>o.getAge()){
return 1;
}else if(age<o.getAge()){
return -1;
}else{
return name.compareTo(o.getName());
}
//return 0;
}
@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 &&
name.equals(person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + 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;
}
}
package com.alpaak.part8.demo8;
import java.util.HashSet;
import java.util.Set;
/**
* HashSet的使用
*/
public class Demo8_HashSet {
public static void main(String[] args) {
Set<String> set1 = new HashSet<>();
set1.add("aaa");
set1.add("bbb");
set1.add("ccc");
System.out.println(set1.add("ddd"));
System.out.println(set1);
boolean flag = set1.add("aaa");//添加的时候,false添加失败--重复添加
System.out.println("flag:"+flag);
System.out.println(set1);
System.out.println("-------------------");
Set<Integer> set2 = new HashSet<>();
set2.add(1);
set2.add(2);
set2.add(3);
set2.add(2);
System.out.println(set2);
Person p1 =new Person("张三",23);
Person p2 = new Person("lisi",56);
Person p3 = new Person("张三",23);
Set<Person> set3 = new HashSet<>();
set3.add(p1);
set3.add(p2);
set3.add(p3);
System.out.println(p1.equals(p3));
System.out.println(set3);
}
}
TreeSet (可以跳过学习)特点:有序,去重 JDK提供的类String,Integer,已经实现了这个Comparable接口;自动有序去重; 自定义的类:实现Comparable接口的compareTo方法,在这个方法里写相应的排序的规则
示例9:package com.alpaak.part8;
import com.alpaak.part8.demo8.Person;
import java.util.Set;
import java.util.TreeSet;
/**
* TreeSet的使用
*/
public class Demo9_TreeSet {
public static void main(String[] args) {
Set<String> set1 =new TreeSet<>();
set1.add("aaa");
set1.add("ccc");
set1.add("ddd");
set1.add("bbb");
System.out.println(set1);
boolean flag = set1.add("aaa");
System.out.println("flag:"+flag);
System.out.println(set1);
Person p1 =new Person("张三",23);
Person p2 = new Person("lisi",56);
Person p3 = new Person("张三",23);
Set<Person> set2 =new TreeSet<>();
set2.add(p1);
set2.add(p2);
set2.add(p3);
System.out.println(set2);
}
}
Comparator接口 : 比较器,实现定制比较。 compare(o1,o2)方法的返回值0,表示重复。
示例10package com.alpaak.part8;
import com.alpaak.part8.demo8.Person;
import java.util.Comparator;
import java.util.TreeSet;
/**
* Comparator的使用
*/
public class Demo10_TreeSetComparator {
public static void main(String[] args) {
//创建集合,并指定比较规则
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("xyz", 20);
Person p2 = new Person("hello", 22);
Person p3 = new Person("zhangsan", 25);
Person p4 = new Person("lisi", 25);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(p4);
System.out.println(persons.toString());
}
}
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> entrySet()
键值匹配的Set集合。
Map实现类
HashMapJDK1.2版本,线程不安全,运行效率快。 允许用null 作为key或是value。 存储结构:哈希表。
示例11:package com.alpaak.part8;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* HashMap的使用
*/
public class Demo11_HashMap {
public static void main(String[] args) {
/*
put(key,value):往map集合中添加键值对
get(key):根据key,获取value;
remove(key):根据key,删除对应的键值对
keySet:key的集合
*/
Map<String,String> map = new HashMap<>();
String s1 = map.put("A", "aaa");//向Map集合中添加键值对
System.out.println("s1:"+s1);
System.out.println(map);
map.put("B","bbb");
map.put("C","ccc");
System.out.println(map);
String s2 = map.put("C", "vvvv");//如果有是重复的key,那么会覆盖原来的value,同时会返回被覆盖的value值
System.out.println("s2:"+s2);
System.out.println(map);
System.out.println("---------------");
String value = map.get("C");//获取指定的key 对应的value
System.out.println("value---->"+value);
System.out.println("------------");
System.out.println("size:"+map.size());
map.remove("C");
System.out.println(map);
//遍历map的key,然后根据key取相应的值,完成遍历
Set<String> keySet = map.keySet();
for(String key:keySet){
System.out.println(key+"------->"+map.get(key));
}
}
}
TreeMap实现了SortedMap接口(Map的子接口),可以对key自动排序,Key需实现Comparable接口。
示例12:package com.alpaak.part8;
import java.util.Map;
import java.util.TreeMap;
/**
* TreeMap的使用
*/
public class Demo12_TreeMap {
public static void main(String[] args) {
Map<String,String> map = new TreeMap<>();
map.put("B","bbb");
map.put("A", "aaa");
map.put("C","ccc");
System.out.println(map);
}
}
四、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)
二分查找
示例13:package com.alpaak.part8;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Collections工具类的使用
*/
public class Demo13_Collections {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
//向指定的集合中添加元素
Collections.addAll(list1,"aaa","bbb","ccc","ddd");
System.out.println(list1);
//找到指定的元素的下标
int index = Collections.binarySearch(list1,"bbb");
System.out.println("index:"+index);
Collections.reverse(list1);//反转指定列表中元素的顺序。
System.out.println(list1);
//使用默认的随机源随机排列指定的列表。
Collections.shuffle(list1);
System.out.println(list1);
//排序
Collections.sort(list1);
System.out.println(list1);
}
}