首页 > 技术文章 > java中的集合总结

shuaifing 2019-05-22 18:00 原文

知识点:

    集合框架和List、set、Map相关集合特点的描述

    Collection接口常用方法,List中相对Collection新增的方法,Collection的遍历(一般for循环,增强for循环,Iterator迭代器循环),TreeSet的自然排序和定制排序

    Map接口常用的方法,Map的遍历(key集遍历,value集遍历,key-value键值对entry集遍历)

    Collections工具类中的常用方法(集合处理线程安全的方法)

      :集合框架

相对与数组来说,集合存储数据避免了长度初始化后,不可改变的弊端

 

注:实线箭头代表继承,虚线箭头代表实现接口,虚线框代表抽象类

 

集合大致分为:

   List接口:存储有序的,可以重复的数据

   Set接口:存储无序的,不可重复的数据(其中不可重复性是指向Set添加相同的元素时,后面的元素不能添加进去,当向Set中添加类的对象时,所在类需要重写equals()和hashCode()方法,并且hashCode方法要与equals()方法一致,这样保证了存储的类的对象元素不可重复性,因为当我们向Set中,添加元素时会先算出元素的hashCode值,每一个hashCode代表元素存储的位置,如果内存中hashCode的位置没有值的话,存入元素,有值的话,则调用equals()方法比较两个元素是否相等,如果相等则不存,不相等则存)

           HashSet:主要实现类

           LinkedHashSet:是HashSet的子类,遍历集合元素时,是按照添加进去的顺序遍历的,适用于频繁遍历,较少的添加

           TreeSet:添加进去的元素必须是同一类

                         添加进集合的元素按照一定规则排序,String,Integer等按照默认的顺序排序

                         如果元素是自定义的类的对象,需要自定义按照类的属性进行排序 ,两种排序 自然排序和定制排序

                          a.自然排序:要求添加进TreeSet中的元素所在的类implements Comparable接口

                                                重写compareTo(Object o)方法,在该方法内部指明元素是按照类的那个属性进行排序的

                                                向TreeSet中添加元素即可,如果不实现Comparable接口,会报运行时异常

                          b.定制排序:创建一个实现Comparator接口的实现类的对象,在实现类中重写compare(Object o1,Object o2 )方法

                                               在compare方法中指明元素是按照类的哪个属性进行排序的

                                               将实现Comparator接口的实现类的对象作为参数传递给TreeSet的构造器中

                                               向TreeSet中添加元素即可,若不实现此接口,会报运行时异常

                            重写compareTo()或者compare()方法需要与equals和hashCode()方法保持一致                 

   Map:存储“键—值”对的数据,key是不可重复的,使用Set存放,value可以重复的,使用Collection存放,一个key-value对构成一个entry(Map.Entry),entry是使用Set存放的

           HashMap:主要的实现类

           LinkedHashMap:是HashMap的子类,使用链表维护添加进Map中的顺序,可以按照添加进Map的顺序实现遍历

           TreeMap:需要按照key所在类的指定属性进行排序,要求key是同一类的对象,对key使用自然排序和定制排序

           Hashtable:古老的实现类,线程安全的,不建议使用

                      子类:Properties:常用来处理属性文件,key和value都是String类型的

    :Collection、List、Set

(1)Collection中常用的方法

      add():想集合里添加元素

      addAll():向集合添加集合

      isEmpty():判断集合是否为空

      clear():清空集合

      contains(Object obj)是否包含某个元素,是返回true,否返回false (如果存入集合元素是自定义类的对象,自定义类要重写equals()方法)

      containsAll(Collection<?> c) 集合中包含集合

      retainAll(Collection coll):取两个集合的共有元素(交集),并返回给当前集合col

      remove(Object obj):删除元素中的元素,删除成功,返回true,失败返回 false

      removeAll():删除集合中一部分元素,返回删除了部分元素后的集合col

      equals(Object o):判断两个集合是否相等

      hashCode():返回元素的hashCode值

      toArray():集合转化为数组  (Object[] objarr=col.toArray())

      iterator():返回一个Iterator接口实现类的对象,进而实现集合遍历 (Iterator iterator=col.iterator();)

(2)List相对Collection,新增加的方法

     1、void add(int index,Object ele):在指定的索引位置index添加元素ele
     2、boolean addAll(int index,Collection eles)
     3、Object remove(int index):删除指定索引位置的元素
     4、Object set(int index,Object ele):设置指定索引位置的元素为ele
     5、Object get(int index):获取指定索引的元素
     6、int indexOf(Object obj):返回obj在集合中首次出现的位置,没有的话,返回-1
     7、int lastIndexOf(Object obj):返回obj在集合中最后一次出现的位置,没有的话,返回-1
     8、List subList(int fromIndex,index toIndex):返回从fromIndex到toIndex结束,左闭右开的集合

     List常用方法:增(add(Object obj))删(remove)改(set(int index,Object obj))查(get(int index)
            插(add(int index,Object obj))长度(size())

(3)TreeSet中添加自定义类的对象的,两种排序方法(a.自然排序 和b.定制排序)

a.自然排序

public class TreeSetTest {
/*
* TreeSet
* 1:向TreeSet中添加的元素必须是同一类
* 2.可以按照添加进集合中的元素指定顺序遍历,像String,包装类等默认的按照从小到大排序遍历
* 3.当向TreeSet中添加自定义类的对象,有两种排序方法(1)自然排序(2)定制排序
* 4.自然排序:自定义类实现java.lang.Comparable接口,并重写其compareTo(Object obj),方法内部,
* 指明按照自定义类的哪一个属性排序
* 5.向TreeSet中,添加元素时,先按照compareTo()进行比较,一旦返回 0,两个对象的属性相同
* 程序会认为两个对象相同,进而后一个对象不能添加到集合中
* 6.compareTo()、hashcode()、equals()三者保持一致
* */

//1、comparable 自然排序
@Test
public void treeSetTest1(){
TreeSet set=new TreeSet();

set.add(new Person("zhangsan",21));
set.add(new Person("wangwu",22));
set.add(new Person("lishi",22));
Iterator iterator=set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
自定义类Person、implements Comparable接口,重写compareTo(Object o)方法,根据类的属性,定义排序规则
public class Person implements Comparable {
private String name;
private Integer age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return age == person.age &&
name.equals(person.name);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

//先根据age排序,当对象age属性相等时,再根据name属性排序
@Override
public int compareTo(Object o) {
if(o instanceof Person){
Person p=(Person)o;
int i=age.compareTo(p.age);
if (i==0){
return name.compareTo(p.name);
}
return i;
}
return 0;
}
}
运行结果:

b.定制排序

  创建一个实现Comparator接口的实现类的对象,在实现类中重写compare(Object o1,Object o2 )方法

  在compare方法中指明元素是按照类的哪个属性进行排序的

  将实现Comparator接口的实现类的对象作为参数传递给TreeSet的构造器中

//2、comparator 定制排序
@Test
public void treeSetTest2(){
//1.创建一个实现了Comparator接口的类的对象
Comparator comparator=new Comparator() {
//2.向TreeSet中添加Man对象,在compare()方法中,指明Man按照那个属性排序的
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Man && o2 instanceof Man) {
Man m1 = (Man) o1;
Man m2 = (Man) o2;
int i = m1.getId().compareTo(m2.getId());
if (i == 0) {
return m1.getName().compareTo(m2.getName());
}
return i;
}
return 0;
}
};

//3.将comparator对象作为形参传递给TreeSet的构造器中
TreeSet set=new TreeSet(comparator);
//4.向TreeSet中添加Comparator接口,compare方法中涉及到的类的对象
set.add(new Man(1001,"zhangsan"));
set.add(new Man(1004,"wangwu"));
set.add(new Man(1004,"lisi"));

Iterator iterator=set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("---------------------");

for (Object o:set){
System.out.println(o);
}
}

Man类重写equals方法和hashCode()方法
public class Man {
private Integer id;
private String name;
private Integer age;
public Man() {
}
public Man(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Man{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Man)) return false;
Man man = (Man) o;
return name.equals(man.name) &&
age.equals(man.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
运行结果:

(4)Collection的遍历(List,Set):迭代器和增强for循环Collection下集合类都适用,一般for循环适用于List,List中有get(i)方法

public class forcirculation {
@Test
public void forcirculationTest(){
Collection col=new ArrayList();
col.add("AA");
col.add("BB");
col.add("CC");
col.add("DD");
//1.一般for循环,适用于List,因为List中增加get(i)方法,而Set是都是Collection的方法没有增加get()方法,无法获取遍历时,无法获得i位置的元素
/*for (int i=0;i<col.size();i++){
System.out.println(col.);
}*/
//2.迭代器遍历集合(数组不能使用迭代器)
Iterator iterator=col.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("===========");
//3.增强for循环(数组可以)
for(Object i:col){
System.out.println(i);
}
System.out.println("===========");
//数组
Object[] objArr=new String[]{"AA","BB","CC"};
for (Object i:objArr){
System.out.println(i);
}
}
}
运行结果:


  :Map key-value键值对
(1)Map中的主要方法
   Object put(Object key,Object value)
Object get(Object key)
Object remove(Object key)
void putAll(Map t)
void clear()
boolean containsKey(Object key)
boolean contaninsValue(Object value)
int size()
boolean isEmpty()
boolean equals(Object obj)
(2)Map的遍历
 public class circulateHashMap {
//遍历HashMap
/*
* Set keySet()
* Collection values()
* Set entrySet()
* */
@Test
public void CirculateHashMapTest(){
HashMap map=new HashMap();
map.put("AA",12);
map.put("BB",null);
map.put(new Person("张三",21),11);

//1.遍历key集
Set set=map.keySet();
Iterator iterator=set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("------------------------------");
//2.遍历value集
Collection cols=map.values();
for (Object o:cols){
System.out.println(o);
}
System.out.println("------------------------------");
//遍历key-value键值对
//方法一 通过Map.entry
Set entrySet=map.entrySet();
for(Object o:entrySet){
//System.out.println(o);
Map.Entry entry=(Map.Entry)o;
System.out.println(entry.getKey()+"===>"+entry.getValue());
}
System.out.println("------------------------------");
//方法二 通过key值获取
Set set2=map.keySet();
for (Object o:set2){
System.out.println(o+"===>"+map.get(o));
}
}
}
运行结果:

   :Collections工具类

  (1)Collections工具类中涉及到方法(Collections是操作Collection和Map的工具类)

 reverse(List):反转List中元素的顺序(Collections.reverse(list)
shuffle(List):对List集合元素进行随机排序
sort(List):根据元素的自然顺序对指定List集合进行升序,从小到大排序
sort(List,Comparator):根据指定的Comparator 产生的顺序对List集合进行排序
swap(List,int i,int j):将指定list集合中,i和j位置的元素进行交换
 Object max(Collection):根据自然顺序,返回集合中最大元素
Object max(Collection,Comparator):根据Comparator指定的顺序,返回集合中最大的元素
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object):返回集合中指定元素出现的次数
void copy(List dest,List src):将src中的元素复制到dec中
boolean replaceAll(List list,Object oldVal,Object newVal):使用newVal替换oldVal的值

其中:copy(List dest,List src)方法desc集合需要初始化长度,不然会报错
List list=new ArrayList();
list.add(123);
list.add(342);
list.add(87);
//List list1=new ArrayList(); 集合长度为0,报数组越界错误
List list1= Arrays.asList(new Object[list.size()]);
System.out.println(list);
System.out.println(list1);
Collections.copy(list1,list);
System.out.println(list1);
运行结果
如果List list1=new ArrayList(),报错



(2)Collections工具类中保证集合安全方法
List list=new ArrayList();
list.add(123);
list.add(342);
list.add(87);
   //保证List集合线程安全
List list2= Collections.synchronizedList(list);

补充:上面关于集合中存放的元素,在实际开发中需要加上泛型的,下一篇博客中有介绍

 

推荐阅读