集合
来源:互联网 发布:ci 数据库配置 编辑:程序博客网 时间:2024/06/07 08:35
集合类
集合类的由来
对象用于封装特有数据,对象多了需要存储;如果对象的个数不确定,就使用集合容器进行存储。
集合特点
1. 用于存储对象的容器。 2. 集合的长度是可变的。 3. 集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体容器。
不断的向上抽取,就形成了集合框架。
数组和集合类区别
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。
数组中可以存储基本数据类型,集合只能存储对象。
集合框架的构成及分类:
Collection 接口
集合框架的顶层Collection接口
Collection 的常见方法
添加
boolean add(Object obj);
boolean addAll(Collection coll);删除
boolean remove(Object obj);
boolean removeAll(Collection coll);
void clear();判断
boolean contains(Object obj);
boolean containsAll(Collection coll);
boolean isEmpty();获取
int size();
Iterator iterator(); 获取迭代器其他
boolean retainAll(Collection coll);取交集
Object toArray();将集合转成数组
Collection
|–List:有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素。
|–Set:元素不能重复,无序。
List
List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以重复。
|–Vector:内部是数组数据结构,是同步的。增删,查询都很慢。
|–ArrayList:内部是数组数据结构,是不同步的,替代了Vector,查询的速度快。
|–LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
List 特有的常见方法有一个共性特点就是都可以操作角标
添加
void add(index,element) 在指定的索引位插入元素。
void addAll(index,collection) 在指定的索引位插入一堆元素。删除
Object remove(index) 删除指定索引位的元素。 返回被删的元素
修改
Object set(index,element) 对指定索引位进行元素的修改
获取:
Object get(index) 根据角标获取元素
int indexOf(object) 根据元素获取角标,从前往后查找
int lastIndexOf(object) 根据元素获取角标,从后往前查找
List subList(from,to) 截取一段集合List集合可以完成对元素的增删改查。
import java.util.ArrayList;import java.util.List;public class ListDemo{ public static void main(String[] args){ List list = new ArrayList(); show(list); } public static void show(List list){ //添加元素 list.add( "abc1" ); list.add( "abc2" ); list.add( "abc3" ); System.out.println(list); //插入元素 list.add(1, "abc2" ); //删除元素 System.out.println( "remove:" + list.remove(2)); //修改元素 System.out.println( "set:" + list.set(1,"abc8" )); //获取元素: System.out.println( "get:" + list.get(0)); //获取子列表 System.out.println( "sublist:" + list.subList(1,2)); System.out.println(list); }}
在迭代器(Iterator)获取数据的过程中,不要使用集合操作元素,会出现异常,可以使用 Iterator 接口的子接口ListIterator 来实现在迭代过程中完成对元素的增删改查,只有 list 集合具备该迭代功能。
Set
Set 中元素不可以重复,是无序。
Set接口中的方法和Collection 一致。
|–HashSet:内部数据结构是哈希表,是不同步的。
|–LinkedHashSet:有序,hashset的子类。
|–TreeSet:可以对Set集合中的元素进行排序,是不同步的。
HashSet
HashSet 集合保证元素唯一性是通过元素的hashCode方法,和equals方法完成的。
当元素的hashCode值相同时,才继续判断元素的equals是否为true。 如果为true,那么视为相同元素,不存。如果为false,那么存储。 如果hashCode值不同,那么不判断equals,从而提高对象比较的速度。
哈希表的原理:
- 对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值 称为哈希值。
- 哈希值就是这个元素的位置。
- 如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 +1顺延。
- 存储哈希值的结构,我们称为哈希表。
- 既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。 这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。
对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。
对于HashSet集合,判断元素是否存在,或者删除元素,底层依据的是hashCode方法和equals方法。
import java.util.HashSet;import java.util.Iterator;class Person{ public String name; public int age; public Person(){ } public Person(String name,int age){ this.name = name; this.age = age; } public int hashCode(){ return name.hashCode() + age * 39; } public boolean equals(Object obj){ if(this == obj) return true ;//同一个对象放两次,直接返回true if(!(obj instanceof Person)) throw new ClassCastException("类型错误"); Person p = (Person)obj; return this .name.equals(p.name) && this.age == p.age; }}public class HashSetTest{ public static void main(String[] args){ HashSet hs = new HashSet(); hs.add( new Person("lisi4" ,24)); hs.add( new Person("lisi7" ,27)); hs.add( new Person("lisi1" ,21)); hs.add( new Person("lisi9" ,29)); hs.add( new Person("lisi7" ,27)); Iterator it = hs.iterator(); while(it.hasNext()){ Person p = (Person)it.next(); System.out.println(p.getName() + "..." + p.getAge()); } }}
TreeSet
TreeSet 用于对 Set 集合进行元素的指定顺序排序,排序需要依据元素自身具备的比较性。
TreeSet 集合的底层是二叉树进行排序的。
TreeSet方法保证元素唯一性的方式是参考比较方法的结果是否为0,如果是 0,视为两个对象重复,不存储。
如果元素不具备比较性,在运行时会发生ClassCastException异常。
TreeSet 对元素进行排序有两种方式
1.让元素自身具备比较功能
元素就需要实现Comparable接口,覆盖compareTo方法。
import java.util.Iterator;import java.util.TreeSet;class Person implements Comparable{ public String name; public int age; public Person(){ } public Person(String name,int age){ this.name = name; this.age = age; } public int hashCode(){ return name.hashCode() + age * 39; } public boolean equals(Object obj){ if(this == obj) return true ; if(!(obj instanceof Person)) throw new ClassCastException("类型错误"); Person p = (Person)obj; return this .name.equals(p.name) && this.age == p.age; } public int compareTo(Object o){ Person p = (Person)o; //先按照年龄排序,再按照年龄排序,以免年龄相同的人,没有存进去。 int temp = this.age - p.age; return temp == 0?this.name.compareTo(p.name):temp; }}public class TreeSetDemo{ public static void main(String[] args){ TreeSet ts = new TreeSet(); //以Person对象年龄进行从小到大的排序 ts.add( new Person("zhangsan" ,28)); ts.add( new Person("wangwu" ,23)); ts.add( new Person("lisi" ,21)); ts.add( new Person("zhouqi" ,29)); ts.add( new Person("zhaoliu" ,25)); Iterator it = ts.iterator(); while(it.hasNext()){ Person p = (Person)it.next(); System.out.println(p.getName() + ":" + p.getAge()); } }}
2.让集合自身具备比较功能
定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeSet集合的构造函数。
import java.util.Comparator;import java.util.Iterator;import java.util.TreeSet;//创建了一个根据Person类的name进行排序的比较器。class ComparatorByName implements Comparator{ public int compare(Object o1,Object o2){ Person p1 = (Person)o1; Person p2 = (Person)o2; int temp = p1.getName().compareTo(p2.getName()); return temp == 0?p1.getAge()-p2.getAge() : temp; }}public class TreeSetDemo{ public static void main(String[] args){ TreeSet ts = new TreeSet(new ComparatorByName()); //以Person对象年龄进行从小到大的排序 ts.add( new Person("zhangsan" ,28)); ts.add( new Person("wangwu" ,23)); ts.add( new Person("lisi" ,21)); ts.add( new Person("zhouqi" ,29)); ts.add( new Person("zhaoliu" ,25)); Iterator it = ts.iterator(); while(it.hasNext()){ Person p = (Person)it.next(); System.out.println(p.getName() + ":" + p.getAge()); } }}
如果自定义类即实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么将以比较器的比较规则为准。
Map 集合
Map:一次添加一对元素,Collection一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实Map集合中存储的就是键值对。
map集合中必须保证键的唯一性。
Map常用方法
1、添加
value put(key,value):返回前一个和key关联的值,如果没有返回null。
2、删除
void clear():清空map集合。
value remove(Object key):根据指定的key删除这个键值对。
3、判断
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();
4、获取
value get(key):通过键获取值,如果没有该键返回null。当然可以通过返回null,来判断是否包含指定键。
int size():获取键值对个数。
把map集合转成set的方法:
Set keySet();
Set entrySet();//取的是键和值的映射关系。
对应了两种map取值的方式。
import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;public class MapDemo{ public static void main(String[] args){ Map<Integer,String> map = new HashMap<Integer,String>(); method(map); } public static void method(Map<Integer,String> map){ map.put(8, "王五"); map.put(2, "赵六"); map.put(7, "小强"); map.put(6, "旺财"); //取出map中的所有元素,有两种方式。 //第一种方式,通过keySet方法获取map中所有的键所在的set集合 //在通过set的迭代器获取到每一个键。 //再对每一个键通过map集合的get方法获取其对应的值即可。 Set<Integer> keySet = map.keySet(); Iterator<Integer> it = keySet.iterator(); while(it.hasNext()){ Integer key = it.next(); String value = map.get(key); System.out.println(key + ":" + value); } //第二种方式 //Iterator<Map.Entry<Integer,String>> it = map.entrySet().iterator(); //while(it.hasNext()){ // Map.Entry<Integer,String> me = it.next(); // Integer key = me.getKey(); // String value = me.getValue(); // System.out. println(key + ":" + value); //} }}
Map常用的子类:
|–Hashtable:内部结构是哈希表,是同步的。不允许null作为键,null作为值。
|–Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
|–HashMap:内部结构式哈希表,不是同步的。允许null作为键,null作为值。替代了Hashtable.
|–TreeMap:内部结构式二叉树,不是同步的。可以对Map结合中的键进行排序。
import java.util.HashMap;import java.util.Iterator;class Student { public String name; public int age; public Student(){ } public Student(String name,int age){ this.name = name; this.age = age; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj) return true ; if (obj == null) return false ; if (getClass() != obj.getClass()) return false ; Student other = (Student) obj; if (age != other.age) return false ; if (name == null) { if (other.name != null) return false ; } else if (!name.equals(other.name)) return false ; return true ; }}public class HashMapDemo{ public static void main(String[] args){ //将学生对象和学生的归属地通过键与值存储到map集合中 HashMap<Student,String> hm = new HashMap<Student,String>(); hm.put( new Student("lisi" ,38),"北京"); hm.put( new Student("zhaoliu" ,24),"上海"); hm.put( new Student("xiaoqiang" ,31),"沈阳"); hm.put( new Student("wangcai" ,28),"大连"); hm.put( new Student("zhaoliu" ,24),"铁岭"); Iterator<Student> it = hm.keySet().iterator(); while(it.hasNext()){ Student key = it.next(); String value = hm.get(key); System.out.println(key.getName() + ":" + key.getAge() + "---" + value); } }}
LinkedHashSet,LinkedHashMap 这两个集合可以保证哈希表有存入顺序和取出顺序一致,保证哈希表有序。
import java.util.HashMap;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.Map;public class LinkedHashMapDemo{ public static void main(String[] args){ HashMap<Integer,String> hm = new LinkedHashMap<Integer,String>(); hm.put(7, "zhouqi"); hm.put(3, "zhangsan"); hm.put(1, "qianyi"); hm.put(5, "wangwu"); Iterator<Map.Entry<Integer,String>> it = hm.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Integer,String> me = it.next(); Integer key = me.getKey(); String value = me.getValue(); System.out. println(key + ":" + value); } }}
使用集合的技巧:
- 看到Array就是数组结构,有角标,查询速度很快。
- 看到link就是链表结构:增删速度快,而且有特有方法。
- 看到hash就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖hashCode,equals方法。
- 看到tree就是二叉树,就要想到排序,就想要用到比较。
- 存储的是一个元素时,就用Collection
- 存储对象之间存在着映射关系时,就使用Map集合。
- 保证唯一,就用Set
- 不保证唯一,就用List。
Collections
Collections 是一个工具类,内部提供的都是静态方法。它的出现给集合操作提供了更多的功能。
Collections.sort(list);//list集合进行元素的自然顺序排序。 Collections.sort(list,new ComparatorByLen());///按指定的比较器方法排序。Collections.max(list); //返回list中字典顺序最大的元素。 Collections.binarySearch(list,"zz");//二分查找,返回角标。Collections.reverseOrder();//逆向反转排序。 Collections.shuffle(list);//随机对list中的元素进行位置的置换。
Collection 和 Collections的区别
Collections 是个 Java.util 下的类,是针对集合类的一个工具类,提供一系列静态方法,实现对集合的查找、排序、替换、线程安全化(将非同步的集合转换成同步的)等操作。
Collection 是个 java.util下的接口,它是各种集合结构的父接口,继承于它的接口主要有Set和List,提供了关于集合的一些操作,如插入、删除、判断一个元素是否其成员、遍历等。
数组转集合:
//将arr数组转成list集合。//可以通过list集合中的方法来操作数组中的元素:isEmpty()、contains、indexOf、setArrays.asList(arr);
集合转数组:
Collections.toArray();
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- 集合
- linux 字符设备入门学习笔记
- 【redis】RDB 持久化
- 【USACO3.3.5】游戏(区间dp的滚动数组与编码问题)
- Sparkler:Spark上的爬虫
- 【Linux学习笔记】10:帮助命令man
- 集合
- opencv 中Mat的一些操作
- Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002解决办法
- 图解集合6:LinkedHashMap
- Java 封装器
- 基站<--->LoRaWAN服务器之间的UDP协议通信缺点
- 旅行家的预算(NOIP1999&水题测试2017082301)
- 绽放的花瓣
- 排序基础--(插入排序、交换排序、选择排序、归并排序)