java集合也叫容器
java集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组。
1、存储对象可以考虑:①数组 ②集合
2、数组存储对象的特点:
- 弊端:①一旦创建,其长度不可变。②真实的数组存放的对象的个数是不可直接知道。
3、集合可分为Collection和Map两种体系
Collection接口:
方法:①add(Object obj),addAll(Collection coll),size(),clear(),isEmpty();②remove(Object obj),removeAll(Collection coll),retainAll(Collectioncoll),equals(Object obj),contains(Object obj),containsAll(Collection coll);hashCode()③iterator(),toArray();
Set接口:元素无序、不可重复的集合—-类似高中的“集合”
HashSet、LinkedHashSet、TreeSet
List接口:元素有序,可重复的集合—-“动态”数组,新增的方法:删除:remove(int index)删除set(int index,Object obj)获取get(int index)插入add(int index,Object obj)
ArrayList(主要的实现类)、LinkedList(对于频繁的插入、删除操作)、Vector(古老的实现类、线程安全的)
Map接口:具有映射关系“key-value对”的集合—-类似与高中的“函数”y=f(x)
HashMap、LinkedHashMap、TreeMap、Hashtable(子类:Properties)
实线表继承,虚线表实现
添加进List集合中的元素(或对象)所在的类一定要重写equals()方法
如果存入集合中的元素是自定义类的对象。要求:自定义类要重写equals( )方法!
要求添加进set中的元素所在的类,一定要重写equals()和hashCode()方法。
Set中的元素是如何存储的呢?使用了哈希算法
当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值,此哈希值决定了此对象在Set中的存储位置。若此位置之前没有对象存储,则这个对象直接存储到此位置。若此位置已有对象存储,再通过equals()比较这两个对象是否相同。如果相同,后一个对象就不能再添加进来。
LinkedHashSet:使用链表维护了一个添加进集合中的顺序。导致当我们遍历LinkedHashSet集合元素时,是按照添加进去的顺序遍历的!
LinkedHashSet插入性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。
TreeSet:
1.向TreeSet中添加的元素必须是同一个类的。
2.可以按照添加进集合中的元素的指定的顺序遍历。像String,包装类等默认按照从小到大的顺序遍历。
3. 当向TreeSet中添加自定义类的对象时,有两种排序方法:自然排序和定制排序
自然排序:
1.要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)方法,在此方法中,指明按照自定义类的哪个属性进行排序。
2.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是对象的此对象值相同,但是程序会认为这两个对象相同,进而不能添加进set
compareTo()与hashCode()以及equals()三者保持一致!
定制排序:
1.创建一个实现了Comparator接口的类对象。
向TreeSet中添加Customer类的对象,在此compare()方法中,指明是按照Customer的哪个属性排序的。
2.将此对象作为形参传递给TreeSet的构造器中
3.向TreeSet中添加Comparator接口中的compare方法中涉及的类对象。
Map中的key用Set来存放,不允许重复,即同一个Map对象所对应的类,须重写hashCode()和equals()方法。
重用String类型做Map的“键”。
Map常用方法:
添加删除:
- Object put(Object key,Object value)
- Object remove(Object key)
- void putAll(Map t)
- void clear()
元视图操作的方法:
- Set keySet()
- Collection values()
- Set entrySet()
元素查询的操作:
- Object get(Object key)//获取key的value值。若无此key,则返回null
- boolean containsKey(Object key)
- boolean containsValue(Object value)
- int size()//返回集合的长度
- boolean isEmpty()
- boolean equals(Object obj)
HashMap:
1.key用Set来存放,不可重复。value使用Collection存放的。可重复
一个key-value对,是一个Entry,所有的Entry是用Set存放的,也不可重复。
2.向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同。若相同,则只能够添加进后添加的那个元素。
LinkedHashMap:
1.LinkedHashMap 是 HashMap 的子类
2.使用链表维护添加进Map中的顺序,故遍历Map时,是按添加的顺序遍历的。
TreeMap:
按照添加进Map中的元素的指定属性进行排序。要求:key必须是同一个类的对象!
TreeMap 的 Key 的排序:
- 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
- 定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口
Hashtable:
古老的Map实现类,线程安全,不允许使用null作为key和value.
Properties:
Properties 类是 Hashtable 的子类,该对象用于处理属性文件
由于属性文件里的 key、value 都是字符串类型,所以 Properties 里的 key 和 value 都是字符串类型
存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法
操作集合的工具类:Collections
作Collection以及Map的工具类:Collections
Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法
排序操作:(均为static方法)
reverse(List):反转 List 中元素的顺序
shuffle(List):对 List 集合元素进行随机排序
sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
swap(List,int, int):将指定 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中的内容复制到dest中
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
同步控制:Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题
//Queue接口:队列,是一种先进先出的线性数据结构,LinkedList类实现了queue接口,用途:请求队列,消息队列,任务
@Test
public void test1(){
Queue<String> queue=new LinkedList<>();
queue.add("小明");
queue.add("小黑");
queue.add("小白");
System.out.println(queue.size());//3
System.out.println(queue.peek());//小明 获取头元素,不移除
System.out.println(queue.poll());//小明 获取头元素,移除
System.out.println(queue.size());//2
}
//Deque接口:双端队列
@Test
public void test2(){
Deque<String> deque=new LinkedList<>();
deque.add("小明");
deque.add("小黑");
deque.add("小白");
System.out.println(deque.getFirst());//小明
System.out.println(deque.getLast());//小白
System.out.println(deque.pollLast());//小白,移除尾端元素
}
//Stack类:桟:先进后出
@Test
public void test3(){
Stack<String> s=new Stack<>();
s.push("Bin");
s.push("Tom");
s.push("Lily");
System.out.println(s.peek());//Lily 获取头元素,不移除
System.out.println(s.pop());//Lily
System.out.println(s.pop());//Tom
System.out.println(s.pop());//Bin
}