下面是常用的工具类: 1. 数组 a) 作用 是一种容器,可以在其中放置对象或基本类型数据。从而,实现使用数组管理一组对象。 b) 优势 是一种简单的线性序列,可以快速的访问数组元素,效率高。如果从效率和类型检查的角度讲,数组是最好的。 c) 劣势 不灵活:容量事先定义好,不能随着需求的变化而扩容。 比如:我们在一个用户管理系统中,要把今天注册的所有用户取出来,那么这个用户有多少个?我们在写程序时是无法确定的。如果,你能确定那你就是神了。因此,就不能使用数组。 因此,数组远远不能满足我们的需求。我们需要一种灵活的,容量可以随时扩充的容器来装载我们的对象。这就是我们今天要学习的容器类,或者叫集合框架。
2.list
Collection接口 Collection 表示一组对象,它是集中,收集的意思,就是把一些数据收集起来 Collection接口的两个子接口: Set中的数据没有顺序,不可重复。 List中的数据有顺序,可重复。
Collection接口中定义的方法: boolean add(Object element); boolean remove(Object element); boolean contains(Object element); int size(); boolean isEmpty(); void clear(); Iterator iterator(); boolean containsAll(Collection c); boolean addAll(Collection c); boolean removeAll(Collection c); boolean retainAll(Collection c); //交集 Object[] toArray();
LIST接口 有序的Collection。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set不同,列表通常允许重复的元素。更确切地讲,列表通常允许满足e1.equals(e2) 的元素对 e1 和e2,并且如果列表本身允许 null 元素的话,通常它们允许多个 null 元素。
多了一些跟顺序有关的方法: void add(Object element); void add(int index, Object element); Object get (int index); Object set(int index,Object element);//修改某一位置的元素 Objectremove (int index); int indexOf (Object o);//返回某个元素的索引。如果没有该数据,返回-1 LinkedList:底层用双向链表实现的List。特点:查询效率低,增删效率高,线程不安全。 ArrayList:底层用数组实现的List。特点:查询效率高,增删效率低,线程不安全。 Vector:底层用数组实现的List,特点:线程安全。
如何选用? 线程安全用Vector。 线程不安全,查找较多用ArrayList。增加或删除元素较多用LinkedList
SET接口 HashSet:采用哈希算法实现的Set HashSet的底层是用HashMap实现的,因此,查询效率高。由于采用Hashcode算法直接确定元素的内存地址,增删效率也高。 Set s = new HashSet(); s.add (“hello”); s.add (“world”); s.add (new Integer(4)); s.add (new Double(1.2)); s.add (“hello”); // 相同的元素不会被加入 System.out.println (s);
练习
将list、set中的方法挨个写测试。学习一下。 a) 熟悉debug。使用debug帮助我们理解学习。 b) 熟悉:typeHierarchy(类的层次关系), call Hierarchy(方法调用关系)
Map接口 实现Map接口的类用来存储键(key)-值(value) 对。 Map 接口的实现类有HashMap和TreeMap等。 Map类中存储的键-值对通过键来标识,所以键值不能重复。
HashMap: 线程不安全,效率高. 允许key或value为null HashTable:线程安全,效率低. 不允许key或value为null ashTable的子类,key和value都是string
常用的方法: Object put(Object key, Object value); Object get(Object key); Object remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty(); void putAll(Map t); void clear();
方法测试: Map m1 = new HashMap(); Map m2 = new HashMap(); m1.put(“one”, new Integer(1)); m1.put(“two”, new Integer(2)); m1.put(“three”, new Integer(3)); m2.put(“A”, new Integer(1)); m2.put(“B”, new Integer(2)); System.out.println(m1.size()); System.out.println(m1.containsKey(“one”)); System.out.println(m2.containsValue(new Integer(1))); if (m1.containsKey(“two”)) { int i = ((Integer) m1.get(“two”)).intValue(); System.out.println(i); } Map m3 = new HashMap(m1); m3.putAll(m2); System.out.println(m3);
Iterator接口[雨林木风2] 所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。 Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。 Iterator接口定义了如下方法: boolean hasNext(); //判断是否有元素没有被遍历 Object next(); //返回游标当前位置的元素并将游标移动到下一个位置 void remove(); //删除游标左面的元素,在执行完next之后该 //操作只能执行一次
遍历集合: 遍历List方法1,使用普通for循环:
for(int i=0;i<list.size();i++){ String temp = (String)list.get(i); System.out.println(temp); //list.remove(i); //遍历删除元素,不过不推荐这种方式! }
遍历List方法2,使用增强for循环(应该使用泛型定义类型!): for (String temp : list) { System.out.println(temp); }
遍历List方法3,使用Iterator迭代器: for(Iterator iter = list.iterator();iter.hasNext()😉{ String temp = (String)iter.next(); System.out.println(temp); }
或者: Iterator iter = c.iterator(); while(iter.hasNext()){ Object obj = iter.next(); iter.remove(); //如果要遍历删除集合中的元素,建议使用这种方式! System.out.println(obj); }
遍历Set方法1,: for(String temp:set){ System.out.println(temp); }
遍历Set方法2,使用iterator迭代器 for(Iterator iter = set.iterator();iter.hasNext()😉{ String temp = (String)iter.next(); System.out.println(temp); }
遍历Map
// Map<Integer, Man> maps = new HashMap<Integer, Man>(); Set keySet = maps.keySet(); for(Integer id : keySet){ System.out.println(maps.get(id).name); }
Collections工具类 类 java.util.Collections 提供了对Set、List、Map操作的工具方法。 void sort(List) //对List容器内的元素排序, //排序的规则是按照升序进行排序。 void shuffle(List) //对List容器内的元素进行随机排列 void reverse(List) //对List容器内的元素进行逆续排列 void fill(List, Object) //用一个特定的对象重写整个List容器 int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的 //方法查找特定对象 List aList = new ArrayList(); for (int i = 0; i < 5; i++) aList.add(“a” + i); System.out.println(aList); Collections.shuffle(aList); // 随机排列 System.out.println(aList); Collections.reverse(aList); // 逆续 System.out.println(aList); Collections.sort(aList); // 排序 System.out.println(aList); System.out.println(Collections.binarySearch(aList, “a2”)); Collections.fill(aList, “hello”); System.out.println(aList);
Comparable接口 Ø 问题:上面的算法根据什么确定集合中对象的“大小”顺序? Ø 所有可以“排序”的类都实现了java.lang.Comparable 接口,Comparable接口中只有一个方法 public int compareTo(Object obj); 该方法: § 返回 0 表示 this == obj § 返回正数表示 this > obj § 返回负数表示 this < obj Ø 实现了Comparable 接口的类通过实现 comparaTo 方法从而确定该类对象的排序方式。
public class TestComparable { /**
* @param args
*/
public static void main(String[] args) { List list = new ArrayList(); Student stu1 = new Student(1,“张三”,100); Student stu2 = new Student(2,“张四”,80); Student stu3 = new Student(3,“张五”,90);
list.add(stu1); list.add(stu2); list.add(stu3); System.out.println(list); Collections.sort(list); System.out.println(list); } }
class Student implements Comparable { int id; String name; int score; public Student(int id, String name, int score) { super(); this.id = id; this.name = name; this.score = score; }
public String toString(){ return name+score; }
@Override public int compareTo(Student o) { if(this.score>o.score){ return 1; }else if(this.score<o.score){ return -1; }else { return 0; } } }
equals和hashcode方法: l Collection类对象是否相等对象在调用remove、contains 等方法时需要比较,这会涉及到对象类型的 equals 方法和hashCode方法;对于自定义的类型,需要重写equals 和 hashCode 方法以实现自定义的对象相等规则。 l 注意:Java中规定,两个内容相同的对象应该具有相等的hashcode
什么时候需要我们重写equal,hashcode方法? 这样作的目的就是为了你的类就能够很好的与java的集合框架协同工作。如果我们能够确认我们定义的类不会和java集合类产生关系,那么我们完全没有必要在覆写equals()方法的时候覆写hashCode。
如下情况,可能需要我们重写equal/hashcode方法: 要将我们自定义的对象放入HashSet中处理。 要将我们自定义的对象作为HashMap的key处理。 放入Collection容器中的自定义对象后,可能会调用remove,contains等方法时。
Equal和hashcode的关系和原理: 1. Hashcode并不是内存地址,是内存地址转换而来的。系统通过它也可以确定内存地址。
2. hashcode方法主要用在集合框架中,目的是为了快速比较两个对象是否相等,因为集合框架中的对象很多,每个都使用equals比较效率很差。 每个对象都有一个hashcode,规定: 1、内容相同的对象hashcode肯定相等 2、内容不相同的对象hashcode可能相等也可能不相等
所以如果两个对象的hashcode不相等则两个对象的内容肯定不相等,这样就不必一个一个去比较属性的值了,从而提高对象比较的速度。
可以直接利用eclipse生成equal和hashcode方法,对于我们一般的程序来说已经足够了。 class Man { int id; int age; String name; public Man(int id, int age, String name) { super(); this.age = age; this.name = name; }
public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final Man other = (Man) obj; if (age != other.age) return false; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; }
public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()) ; return result; } }
Ø 泛型(5.0以后增加的!! 以后大家使用容器时,建议大家使用泛型!!)
为什么需要泛型? 1. JDK1.4以前类型不明确: 2. 装入集合的类型都被当作Object对待,从而失去自己的实际类型。 3. 从集合中取出时往往需要转型,效率低,容易产生错误。 泛型的好处: 4. 增强程序的可读性和稳定性。
泛型的使用: List list = new ArrayList(); Set mans = new HashSet(); Map<Integer, Man> maps = new HashMap<Integer, Man>(); Iterator iterator = mans.iterator();
n 常见面试题: 1. Collection 和 Collections的区别。 Collections是个java.util下的类,它包含有各种有关集合操作的静态方法。 Collection是个java.util下的接口,它是各种集合结构的父接口。
2. List, Set, Map是否继承自Collection接口? List,Set是 Map不是
3. ArrayList和Vector的区别。 一.同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的 。 二.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半。
4. HashMap和Hashtable的区别 同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
作用: 经常用于读取资源文件内容
所有的属性的值都相等才算相等。这个可以根据自己的实际情况进行改写。 如果只需要比较id,那么就用id 就可以了。
散列算法。
而如果只用少量的属性采样散列,极端情况会产生大量的散列冲突,如对"人"的属性中,如果用性别而不 是姓名或出生日期,那将只有两个或几个可选的hashcode值,将产生一半以上的散列冲突.
原文链接:https://blog.csdn.net/HarderXin/article/details/6802777