续…集合类框架基础一
三 Set集合
特点:元素不重复,存入的元素无序。
1.1.HashSet 内部由哈希表实现,无序,需要重写hashcode方法和equal方法,来确保存入对象的唯一性。是不同步的。
Example
class Box
{
private int data;
private String name;
public Box() {
super();
// TODO Auto-generated constructor stub
}
public Box(int data, String name) {
super();
this.data = data;
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + data;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Box other = (Box) obj;
if (data != other.data)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class HashSetdemo2 {
public static void main(String []args)
{
HashSet<Box> hs=new HashSet<Box>();
hs.add(new Box(12,"fsr"));
hs.add(new Box(15,"fs23"));
hs.add(new Box(16,"fsr3"));
hs.add(new Box(13,"fsr4"));
hs.add(new Box(15,"fs23"));
hs.add(new Box(16,"fsr3"));
for(Iterator<Box> in =hs.iterator();in.hasNext();)
{
Box b=in.next();
System.out.println(b.getData()+":"+b.getName());
}
}
}
15:fs23
13:fsr4
12:fsr
16:fsr3
通过重写hashcode方法和equal方法是HashSet中的元素保持唯一性。
1.2.HashSet的确定元素唯一性的方式:
①通过哈希函数计算出一个地址值,若此地址没有元素,则存入
②如果计算出的地址已经被占用,则继续调用equals方法把当前存入的元素和占用位置的元素进行比较。在通过equals方法比较后,如果返回值为零。就视为两个元素相同,只保留中的一个进行存储。注意哈希值不同是不需要判断equals方法。
1.3 LinkedHashSet集合
具有可预知迭代顺序的Set接口,由哈希表和链表实现。
HashSet中存储的元素是迭代无序的,而LinkedHashSet可以使迭代有序(即怎么存储的怎么拿出来)。其他方法与Hashset一致。
2.1 TreeSet集合
特点:可以对集合中元素排序。是不同步的。
它的内部数据结构是二叉树。对TreeSet集合中的元素进行排序有两种方式。
方式一:在存入的TreeSet中对象的类中实现Comparable接口,重写ComparaTo方法。
class Person implements Comparable<Person>
{
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
Person(String name ,int age)
{
this.name=name;
this.age=age;
}
public void show()
{
System.out.println(this.getName()+this.getAge());
}
@Override
public int compareTo(Person o) {
int temp=this.getAge()-o.getAge();
return temp==0?this.getName().compareTo(o.getName()):temp;
}
}
public class TreeSetDemo1 {
public static void main(String []args)
{
TreeSet<Person> ts = new TreeSet<Person>();
ts.add(new Person("zhang",23));
ts.add(new Person("zhu",13));
ts.add(new Person("wang",21));
ts.add(new Person("liu",63));
ts.add(new Person("liu",62));
for(Iterator<Person> in =ts.iterator();in.hasNext();)
{
Person p=in.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
}
方式二:在构造器中传入自定义比较器进行比较
①自定义一个类实现Comparator接口
②实现Compare方法
class MycomparaByName implements Comparator<Person>
{
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
}
注意:方式一是按照对象中的自然顺序进行排序,如果不需要按照对象中的自然顺序,可以自定义比较器,自定义排序方式。
四 Map集合
Map集合是双列集合,由键值对的方式进行存储。
1hashtable
内部结构是哈希表,是同步的。不允许null作为键,不允许null作为值,和Vector一样,由于效率问题,新出了hashmap和Treemap。在实现的子类Prorities中用来存储键值对的配置文件的信息,可以与IO技术相结合。
2 hashmap
内部结构是哈希表,是不同步的。允许null作为键,允许null作为值。
与HashSet一样也需要重写euqals方法和hashcode方法,确保键的唯一性。
2.1Example
class Car
{
private String type;
private int password;
public Car() {
super();
// TODO Auto-generated constructor stub
}
public Car(String type, int password) {
super();
this.type = type;
this.password = password;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getPassword() {
return password;
}
public void setPassword(int password) {
this.password = password;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + password;
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Car other = (Car) obj;
if (password != other.password)
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
}
public class HashMapdemo {
public static void main(String []args)
{
HashMap<Car,Integer> hs=new HashMap<Car,Integer>();
hs.put(new Car("ford",5134), 25000);
hs.put(new Car("auto",4224), 25000);
hs.put(new Car("avdi",5354), 225000);
hs.put(new Car("ford",5134), 125000);
Set<Car> keyset=hs.keySet();
Iterator<Car> in=keyset.iterator();
while(in.hasNext())
{
Car c=in.next();
System.out.println(c.getPassword()+c.getType()+":"+hs.get(c));
}
}
}
3.1Treemap
内部结构是二叉树,是不同步的,可以对map集合中的键进行排序
与TreeSet一样,也有两种方法来进行排序操作。
方式一:在存入的TreeSet中对象的类中实现Comparable接口,重写ComparaTo方法。
方式二:在构造器中传入自定义比较器进行比较
①自定义一个类实现Comparator接口
②实现Compare方法
练习1
通过HashMap来计算出一段字符串的字符出现次数
public class HashMaptest {
public static void main(String []args)
{
String str="datwejgdsdfasdfhqaz";
char [] ch=str.toCharArray();
TreeMap<Character,Integer> hs=new TreeMap<Character,Integer>();
for(int i=0;i<ch.length;i++)
{
Integer value=hs.get(ch[i]);
if(value==null)
{
hs.put(ch[i], 1);
}
else
{
hs.put(ch[i], value+1);
}
}
Set<Map.Entry<Character, Integer>> EntrySet=hs.entrySet();
Iterator<Map.Entry<Character, Integer>> in=EntrySet.iterator();
while(in.hasNext())
{
Map.Entry<Character, Integer> map=in.next();
System.out.println( "key:"+ map.getKey() + "value:"+map.getValue());
}
}
}
练习二 处理一个键对应多个值的情况,我们可以把值当做为单列集合存入Map集合。
class Person
{
private String name;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Area
{
private String location;
}
public class Maptest {
public static void main(String []args)
{
TreeMap<String,Person> ts=new TreeMap<String,Person>();
ts.put("beijing", new Person("liqiang"));
ts.put("beijing", new Person("wuwang"));
ts.put("beijing", new Person("fanqi"));
Set<Map.Entry<String, Person>> st=ts.entrySet();
Iterator<Map.Entry<String, Person>> in= st.iterator();
while(in.hasNext())
{
Map.Entry<String, Person> map=in.next();
System.out.println(map.getKey()+":"+map.getValue().getName());
}
}
}
打印结果为:beijing:fanqi
可以看到map中键相同,值覆盖。
所以我们如果在相同键存储多个值的时候 可以把值设为单列集合
class Person
{
private String name;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Area
{
private String location;
}
public class Maptest {
public static void main(String []args)
{
LinkedList<Person> link=new LinkedList<Person>();
link.add(new Person("liqiang"));
link.add(new Person("wuwang"));
link.add(new Person("fanqi"));
TreeMap<String,LinkedList> ts=new TreeMap<String,LinkedList>();
ts.put("beijing",link);
Set<Entry<String,LinkedList>> st=ts.entrySet();
Iterator<Entry<String, LinkedList>> in= st.iterator();
while(in.hasNext())
{
Entry<String, LinkedList> map=in.next();
for(Iterator<Person> in2=map.getValue().iterator();in2.hasNext();)
{
Person pp=in2.next();
System.out.println(map.getKey()+":"+pp.getName());
}
}
输出结果:
beijing:liqiang
beijing:wuwang
beijing:fanqi
四 collections工具类 是集合的工具类里面的方法都是静态的。
static
<T> boolean addAll(Collection<? super T> c, T... elements)
将所有指定元素添加到指定 collection 中。
static
<T> Queue<T> asLifoQueue(Deque<T> deque)
以后进先出 (Lifo) Queue 的形式返回某个 Deque 的视图。
static
<T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
使用二分搜索法搜索指定列表,以获得指定对象。
static
<T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
使用二分搜索法搜索指定列表,以获得指定对象。
static
<E> Collection<E> checkedCollection(Collection<E> c, Class<E> type)
返回指定 collection 的一个动态类型安全视图。
static
<E> List<E> checkedList(List<E> list, Class<E> type)
返回指定列表的一个动态类型安全视图。
static
<K,V> Map<K,V> checkedMap(Map<K,V> m, Class<K> keyType, Class<V> valueType)
返回指定映射的一个动态类型安全视图。
static
<E> Set<E> checkedSet(Set<E> s, Class<E> type)
返回指定 set 的一个动态类型安全视图。
static
<K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K,V> m, Class<K> keyType, Class<V> valueType)
返回指定有序映射的一个动态类型安全视图。
static
<E> SortedSet<E> checkedSortedSet(SortedSet<E> s, Class<E> type)
返回指定有序 set 的一个动态类型安全视图。
static
<T> void copy(List<? super T> dest, List<? extends T> src)
将所有元素从一个列表复制到另一个列表。
static boolean disjoint(Collection<?> c1, Collection<?> c2)
如果两个指定 collection 中没有相同的元素,则返回 true。
static
<T> List<T> emptyList()
返回空的列表(不可变的)。
static
<K,V> Map<K,V> emptyMap()
返回空的映射(不可变的)。
static
<T> Set<T> emptySet()
返回空的 set(不可变的)。
static
<T> Enumeration<T> enumeration(Collection<T> c)
返回一个指定 collection 上的枚举。
static
<T> void fill(List<? super T> list, T obj)
使用指定元素替换指定列表中的所有元素。
static int frequency(Collection<?> c, Object o)
返回指定 collection 中等于指定对象的元素数。
static int indexOfSubList(List<?> source, List<?> target)
返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
static int lastIndexOfSubList(List<?> source, List<?> target)
返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
static
<T> ArrayList<T> list(Enumeration<T> e)
返回一个数组列表,它按返回顺序包含指定枚举返回的元素。
static
<T extends Object & Comparable<? super T>>
T max(Collection<? extends T> coll)
根据元素的自然顺序,返回给定 collection 的最大元素。
static
<T> T max(Collection<? extends T> coll, Comparator<? super T> comp)
根据指定比较器产生的顺序,返回给定 collection 的最大元素。
static
<T extends Object & Comparable<? super T>>
T min(Collection<? extends T> coll)
根据元素的自然顺序 返回给定 collection 的最小元素。
static
<T> T min(Collection<? extends T> coll, Comparator<? super T> comp)
根据指定比较器产生的顺序,返回给定 collection 的最小元素。
static
<T> List<T> nCopies(int n, T o)
返回由指定对象的 n 个副本组成的不可变列表。
static
<E> Set<E> newSetFromMap(Map<E,Boolean> map)
返回指定映射支持的 set。
static
<T> boolean replaceAll(List<T> list, T oldVal, T newVal)
使用另一个值替换列表中出现的所有某一指定值。
static void reverse(List<?> list)
反转指定列表中元素的顺序。
static
<T> Comparator<T> reverseOrder()
返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
static
<T> Comparator<T> reverseOrder(Comparator<T> cmp)
返回一个比较器,它强行逆转指定比较器的顺序。
static void rotate(List<?> list, int distance)
根据指定的距离轮换指定列表中的元素。
static void shuffle(List<?> list)
使用默认随机源对指定列表进行置换。
static void shuffle(List<?> list, Random rnd)
使用指定的随机源对指定列表进行置换。
static
<T> Set<T> singleton(T o)
返回一个只包含指定对象的不可变 set。
static
<T> List<T> singletonList(T o)
返回一个只包含指定对象的不可变列表。
static
<K,V> Map<K,V> singletonMap(K key, V value)
返回一个不可变的映射,它只将指定键映射到指定值。
static
<T extends Comparable<? super T>>
void sort(List<T> list)
根据元素的自然顺序 对指定列表按升序进行排序。
static
<T> void sort(List<T> list, Comparator<? super T> c)
根据指定比较器产生的顺序对指定列表进行排序。
static void swap(List<?> list, int i, int j)
在指定列表的指定位置处交换元素。
static
<T> Collection<T> synchronizedCollection(Collection<T> c)
返回指定 collection 支持的同步(线程安全的)collection。
static
<T> List<T> synchronizedList(List<T> list)
返回指定列表支持的同步(线程安全的)列表。
static
<K,V> Map<K,V> synchronizedMap(Map<K,V> m)
返回由指定映射支持的同步(线程安全的)映射。
static
<T> Set<T> synchronizedSet(Set<T> s)
返回指定 set 支持的同步(线程安全的)set。
static
<K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
返回指定有序映射支持的同步(线程安全的)有序映射。
static
<T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
返回指定有序 set 支持的同步(线程安全的)有序 set。
static
<T> Collection<T> unmodifiableCollection(Collection<? extends T> c)
返回指定 collection 的不可修改视图。
static
<T> List<T> unmodifiableList(List<? extends T> list)
返回指定列表的不可修改视图。
static
<K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
返回指定映射的不可修改视图。
static
<T> Set<T> unmodifiableSet(Set<? extends T> s)
返回指定 set 的不可修改视图。
static
<K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> m)
返回指定有序映射的不可修改视图。
static
<T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)
返回指定有序 set 的不可修改视图。
主要的有 collection.synchronizedxx方法
在Vector和hashtable中都是线程安全的,而其他集合都不是线程安全的,我们怎么获得一个线程安全的集合呢?
通过调用静态的collection.synchronizedXX方法,返回一个线程安全的集合。
synchronizedxx方法原理
class MyCollection
{
public static Collection synchronizedxx()
{
return new SynCollection();
}
class SynCollection implements Collection
{
private Collection coll;
private SynCollection(Collection coll)
{
this.coll=coll;
}
synchronized boolean add(Collection coll)
{
return coll.add();
}
synchronized boolean remove (Collection coll)
{
return coll.remove(o)
}
}
}
其实调用Synchronized方法返回的是一个内部类对象。
五 arrays工具类 里面的方法都是静态的
有许多对数组进行操作的方法。开发更加便捷
1.其中List asList(数组)能将数组转化为List集合
好处:可以使用集合的方法来操作数组元素。
注意:①数组的长度是固定的,对于集合的增加,删除是不可以使用的。
②如果数组的元素是基本数据类型,转化成集合是直接将数组作为集合对象存储。如果数组的元素是对象,转化成集合是直接将数组中对象存储到集合。
2.也可以把集合转化为数组。Collection.toArray方法
目的:限制对集合的操作,使使用者不能对集合进行修改。
注意:toArray方法需要传递一个指定类型的数组,如果长度小于集合的元素,则会自动扩充,如果长度大于结合的元素,则大于部分存储的是null。