黑马程序员--java集合,黑马程序员--java
黑马程序员--java集合,黑马程序员--java
------- android培训、java培训、期待与您交流! ----------java集合
集合概述:
Java 集合就像一种容器,可以把多个对象的引用放入容器中。Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组,Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组。
Java 集合可分为Set、List 和 Map 三种体系:
- Set:无序、不可重复的集合
- List:有序,可重复的集合
- Map:具有映射关系的集合
在Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理;从 Java5 增加了泛型以后,Java 集合可以记住容器中对象的数据类型。
关于Collection和Collections:
1. Collection是集合类的一个顶级接口,Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
2.在collection无法获取指定的元素,但可以遍历所有的元素。有两种方法:
- 使用增强for循环 for(Collection coll:collection){…}
- 使用Iterator迭代器, Iterator 仅用于遍历集合,Iterator 本身并不提供承装对象的能力。如果需要创建 Iterator 对象,则必须有一个被迭代的集合。Iterator it=collection.Iterator();while(it.hasNext()){…};
- reverse(List):反转 List 中元素的顺序
- shuffle(List):对List 集合元素进行随机排序
- sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
- sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
- swap(List,int, int):将指定 list 集合中的i 处元素和 j 处元素进行交换
Set集合:
1. Set 集合不能包含相同的元素,集合内的元素是无序的。
2. Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法 。
HashSet:
1. HashSet:不能存储相同的元素。不能保证元素的排列顺序,不是线程安全的,集合元素可以使 null。
2.Set 接口的最典型实现,通常使用 Set 集合时都使用这个实现类。
3.按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。
4.当向 HashSet 集合中存入一个元素时,HashSet会调用该对象的 hashCode() 方法来得到该对象的hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置,这就是不能保证元素排列顺序的原因。
5.如果两个对象的 equals() 方法返回 true,一般的他们的hashCode()值也相等。但我们可以通过重写equals方法让两个不同对象equals方法返回true,同时重写hashcode方法返回不同的值。所以,尽管两个对象” 表面”相同,还是能添加到HashSet集合中的,且他们会插入不同的位置。如下面代码所示:
import java.util.HashSet;
import java.util.Set;
public class testHashSet {
public static void main(String[] args) {
Student stu1 = new Student("AA", 12);
Student stu2 = new Student("AA", 12);
Set set = new HashSet();
System.out.println(stu1.equals(stu2));//true ,表明stu1和stu2为相同的元素
set.add(stu1);
set.add(stu2);
System.out.println(set.size());//2,表明成功添加了"相同"的元素
}
}
class Student {
private String name;
private int age;
public Student() {
}
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 Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
// 重写hashcode方法,让其每执行一次返回的值都加1
private static int initHashCode = 1;
@Override
public int hashCode() {
return initHashCode++;
}
// 重写equals,让其只要判定对象内容相等就返回true.
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Student))
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;
}
TreeSet:
1. TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。
2. TreeSet 支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet采用自然排序。
- 自然排序:默认情况下集合中的元素必须实现Comparable接口. 实现 Comparable 的类必须实现 compareTo(Object obj) 方法。
- 定制排序:需要在创建 TreeSet 集合对象时,提供一个 Comparator 接口的实现类对象。由该 Comparator 对象负责集合元素的排序逻辑 。下面是定制排序的代码片段:
Comparator comparator =new Comparator() {
//------------定制排序代码片段------------------
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Person1 && o2 instanceof Person1){
Person1 p1=(Person1) o1;
Person1 p2=(Person1)o2;
return p1.getAge()-p2.getAge();
}
throw new ClassCastException("不能转换为person1类");
}
};
TreeSet set=new TreeSet(comparator);
List:
1.List 代表一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引
2.List 允许使用重复元素,可以通过索引来访问指定位置的集合元素。
3.List 默认按元素的添加顺序设置元素的索引。
4.List 额外提供了一个 listIterator() 方法,该方法返回一个 ListIterator 对象,ListIterator 接口继承了 Iterator 接口,提供了专门操作 List 的方法.
ArrayList 和 Vector:
1.ArrayList和 Vector 是 List 接口的两个典型实现,,ArrayList 是线程不安全的,而 Vector 是线程安全的, 通常建议使用 ArrayList。
2.Arrays.asList(…) 方法返回的 List 集合即不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…) 返回值是一个固定长度的 List 集合。
Map:
1.Map 用于保存具有映射关系的数据, Map 中的key 和 value 都可以是任何引用类型的数据
2.Map 中的Key 不允许重复,即同一个 Map 对象的任何两个 Key 通过 equals 方法比较中返回 false.
HashMap & Hashtable:
1. Hashtable 不允许使用 null 作为 key 和 value,而HashMap 可以.
2. Hashtable 是一个古老的 Map 实现类,不建议使用
3. Hashtable 是一个线程安全的 Map 实现,但 HashMap 是线程不安全的。
4.Hashtable 、HashMap 判断两个 Key 相等的标准是:两个 Key 通过 equals 方法返回true,hashCode 值也相等。5. Hashtable 、HashMap 判断两个 Value相等的标准是:两个 Value 通过 equals 方法返回 true
TreeMap:
1. TreeMap 存储 Key-Value 对时,需要根据 Key 对 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。
2. TreeMap 的 Key 的排序:
- 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口, 而且所有的 Key 应该是同一个类的对象
- 定制排序:创建 TreeMap 时,传入一个Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口 。
Properties:
1.Properties类是 Hashtable 的子类,该对象用于处理属性文件
2.由于属性文件里的 key、value 都是字符串类型,所以 properties 里的 Key 和Value 都是字符串类型的。总结:
Collection接口是Set和List的父接口,不是Map的父接口,Map和Collection处于同一级别。
Set :里的元素 无序、不重复。
HashSet:无序、不重复、元素可为null。
TreeSet:有序、不重复、元素可为null。
List: 有序、可重复、按添加元素的顺序排序。
ArrayList: 有序、可重复、元素可为空,线程不安全。
Vector:古老的结合,一般不使用、线程安全。
Map:存放键值对集合、key不能重复。
HashMap:不能保证key-value对的顺序、key不能重复,key可为null。
Hashtable:不能保证key-value对的顺序、key不能重复、key不能null、古老的Map实现类、不建议使用。
TreeMap:根据key对key-value对进行排序、key不能重复、key可为null。
通过对比,可以发现HashSet的元素和HashMap的key对应的,TreeSet和TreeMap的key是对应的,Set和Map也是对应的,那么Set和Map是否存在着联系(其实还有未提到的LinkHashSet和LinkHashMap也是对应的)?
我们找到HashSet的源码可以发现:
package java.util;
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<E,Object>();
}
public HashSet(Collection<? extends E> c) {
map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<E,Object>(initialCapacity, loadFactor);
}
public HashSet(int initialCapacity) {
map = new HashMap<E,Object>(initialCapacity);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}
public Iterator<E> iterator() {
return map.keySet().iterator();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean contains(Object o) {
return map.containsKey(o);
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
public void clear() {
map.clear();
}
public Object clone() {
try {
HashSet<E> newSet = (HashSet<E>) super.clone();
newSet.map = (HashMap<E, Object>) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out any hidden serialization magic
s.defaultWriteObject();
// Write out HashMap capacity and load factor
s.writeInt(map.capacity());
s.writeFloat(map.loadFactor());
// Write out size
s.writeInt(map.size());
// Write out all elements in the proper order.
for (Iterator i=map.keySet().iterator(); i.hasNext(); )
s.writeObject(i.next());
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden serialization magic
s.defaultReadObject();
// Read in HashMap capacity and load factor and create backing HashMap
int capacity = s.readInt();
float loadFactor = s.readFloat();
map = (((HashSet)this) instanceof LinkedHashSet ?
new LinkedHashMap<E,Object>(capacity, loadFactor) :
new HashMap<E,Object>(capacity, loadFactor));
// Read in size
int size = s.readInt();
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
E e = (E) s.readObject();
map.put(e, PRESENT);
}
}
}<strong>
</strong>
在调用HashSet的Add(Object ),remove(Object o) ...等方法时,实际调用的是HashMap的Add和remove..等方法
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<E,Object>();
}
这里的HashMap的vaule实际是个Object常量,而HashSet的元素,被当做了Map的Key.
所以我们可以得出结论:
- Set由Map来定义。
- 在调用Set子类接口的实现类(如HashSet)的方法时,实际调用的是Map对应子类接口的实现类的方法。
- add(obj)实际是把obj放入了Map中的key中。
相关文章
- 暂无相关文章
用户点评