一、关于集合
集合是封存对象的容器,比数组的功能更为强大,Collections类提供了对集合操作的多种便捷方法,从数据结构上讲,集合实现了多种数据结构,树、图、哈希表、顺序存储、链式存储等等。而数组仅仅实现了顺序存储。对于同为顺序结构的数组和ArrayList来讲,效率上数组更高,因为ArrayList其实现也是封装了数组,但集合提供了多种操作和长度可变等许多优点。对于其他存储结构来说,集合优势更为明显,可以使用树结构进行元素排序,Map实现键值对存储等等。
二、Collection接口
Collection接口下主要成员如下
如图所示,不同的集合都实现了不同的数据结构、因此在功能和存取效率上也有所差别。
List中ArrayList和LinkList,ArrayList的存储结构与数组一样,在内存中数据是连续出现的,因此查找元素效率较高,但对于增删操作时涉及到元素位置的变动因此增删操作效率较低。而LinkList特性是数据不是连续的,要靠每个节点中指向下一个节点的地址来将数据串联起来,多以查找较慢,但增删操作时知识改变指针地址即可,所以增删效率较高。
对于Set集合中TreeSet实现了二叉树的存储结构,或平衡二叉树,好处是TreeSet在存储的同时也要进行比较,以便生成二叉树,而读取该集合就是对二叉树的遍历过程,使原本无序元素变得有序,正因这样存入的元素或对象必须可比较,即必须实现Comparable接口或在新建实例时传入一个自定义的比较器。
对于实现了哈希表的HashSet集合来讲,因为每次存取都会根据元素自身的hashcode以及散列函数算出要存入的位置,因此每次存取都是相对固定的,不需要向树或线性表一样进行遍历,因此效率应该是最高的。
Collection接口常用方法:
boolean add(Object o):该方法用于向集合里面添加一个元素,若集合对象被添加操作改变了,返回true.
boolean addAll(Collection c):把集合c里面的所有元素添加到指定集合里面去,如果集合对象被添加操作改变了返回true.
void clear():清除集合里面的所有元素,将集合长度变为0。
boolean contains(Object o):返回集合里是否包含指定的元素。
boolean containsAll(Collection c):返回集合里是否包含集合c内所有的元素。
boolean isEmpty():返回集合是否为空(长度是否为0)。
Iterator iterator():返回一个Iterator对象,用于遍历集合里的元素。
boolean remove(Object o):删除集合中指定元素o。
boolean removeAll(Collection c):从集合中删除集合c里面的元素。若删除一个或以上返回true。
boolean retainAll(Collection c):从集合中删除集合c里不包含的元素。
int size():得到集合元素的个数。
Object[] toArray():把集合转成一个数组,所有集合元素编程数组元素。
三、迭代器Iterator
取出Collection集合元素的主要方式增强For和迭代器,其中增强For也利用的是Iterator
<span style="font-size:14px;">public class CollectionTest {
public static void main(String[] args) {
List<String> list=new LinkedList<String>();
list.add("北京");
list.add("上海");
list.add("广州");
list.add("深圳");
for (String string : list) {
System.out.println(string);
}
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
System.out.println(string);
}
}
}
</span>
四、TreeSet集合
使用TreeSet 对student类按年龄age排序
TreeSet传入的元素必须实现Comparable接口复写compareTo方法,TreeSet存入的元素不允许重复,当存入重复元素时,返回false,而判断是否重复就是依靠compareTo方法的返回值,当返回0时表示两个对象相等。
public class CollectionTest {
public static void main(String[] args) {
Set<Student> set = new TreeSet<Student>();
set.add(new Student(20, "张三"));
set.add(new Student(17, "张三"));
set.add(new Student(17, "李四"));
for (Iterator<Student> iterator = set.iterator(); iterator.hasNext();) {
Student student = (Student) iterator.next();
System.out.println(student);
}
}
}
class Student implements Comparable<Student> {
private int age;
private String name;
@Override
public String toString() {
// TODO Auto-generated method stub
return age + "--" + name;
}
public Student(int age, String name) {
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o) {
// TODO Auto-generated method stub
if (this.age == o.age)
return this.name.compareTo(o.name);
return this.age - o.age;
}
}
上述代码中Student实现了comparable接口,而当某个类已经实现了该接口后,想用另一种排序方式,则可以传入一个比较器传给TreeSet对象,以覆盖掉元素自身的比较方法。
如下边的例子,String类的排序是自然排序,而现在想要按照字符串长短排序,可以建立自定义的比较器。
public class CollectionTest {
public static void main(String[] args) {
Set<String> set = new TreeSet<String>(new MyComparator());
set.add("aaaaaaa");
set.add("bbbbb");
set.add("ccc");
for (Iterator iterator = set.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
System.out.println(string);
}
}
}
class MyComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
if (o1.length() == o2.length())
return o1.compareTo(o2);
return o1.length() - o2.length();
}
}
五、HashSet集合
HashSet同样不能存重复元素,判断吃否是重复元素的依据是先判断对象的HashCode,如果不一样则直接存入集合,若一样则判断equals方法返回的布尔值。若equals方法也返回false,则可存入集合。
public class CollectionTest {
public static void main(String[] args) {
Set<Student> set = new HashSet<Student>();
set.add(new Student(18, "李磊"));
set.add(new Student(19, "李雷"));
set.add(new Student(19, "李雷"));
set.add(new Student(20, "韩梅梅"));
for (Iterator<Student> iterator = set.iterator(); iterator.hasNext();) {
Student student = (Student) iterator.next();
System.out.println(student);
}
}
}
class Student {
private int age;
private String name;
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return age + name.hashCode();
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if (!(obj instanceof Student))
return false;
Student student = (Student) obj;
return this.name.equals(student.name) && this.age == student.age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return name + "----" + age;
}
}
六、Map
常用方法:
void clear():删除该Map对象中所有的key-value对。也就是清理该集合;
boolean containsKey(Object key):查询Map中是否包含指定的key;
boolean containsValue(Object value):查询Map中是否包含至少一个value;
Set entrySet():返回Map所包含的key-value对所组成的Set集合,每个集合元素都是Map.Entry对象(Entry是Map内部类);
Object get(Object key):返回指定key所对应的value,若此Map中不包含该key,返回null;
boolean isEmpty():判断Map集合是否为空;
Set keySet():返回该Map中所有key所组成的Set集合;
Object put(Object key,Object value):添加一个key-value对,若Map中已有与key相等的key-value对,则新的key-value对覆盖原来的key-value对;
void putAll(Map m):将m中的key-value赋值到调用该方法的Map对象中;
Object remove(Object key):删除指定key所对应的key-value对,返回本删除key所关联的value,若key不存在,返回null;
int size():返回该Map里面key-value对的个数;
Collection values():返回Map里所有value组成的Collection。
public class CollectionTest {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
System.out.println("put:"+map.put("111","黑马"));
System.out.println("put:"+map.put("111","程序员111"));
map.put("222","程序员222");
map.put("333","程序员333");
System.out.println("containsKey:"+map.containsKey("444"));
System.out.println("remove:"+map.remove("111"));
System.out.println("get:"+map.get("555"));
map.put("555",null);
System.out.println("get:"+map.get("555"));
Collection<String> coll = map.values();
System.out.println(coll);
System.out.println(map);
}
}
Map集合元素的两种取出方式
public class CollectionTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("1", "111");
map.put("2", "222");
map.put("3", "333");
map.put("4", "444");
map.put("5", "555");
// 方式一
Set<Entry<String, String>> set = map.entrySet();
for (Entry<String, String> entry : set) {
System.out.println(entry.getKey() + "---" + entry.getValue());
}
// 方式二
Set<String> set_key = map.keySet();
for (String string : set_key) {
System.out.println(string + "---" + map.get(string));
}
}
}
取出一个字符串中字母出现的次数。如:字符串:"abcdekka27qoq" ,输出格式为:a(2)b(1)k(2)...
public static void main(String[] args) {
String str="cabcdekkaqoq";
StringBuffer result=new StringBuffer();
Map<Character, Integer> map=new TreeMap<Character, Integer>();
for (int i = 0; i < str.length(); i++) {
char ch=str.charAt(i);
if(map.containsKey(ch)){
map.put(ch, (int)map.get(ch)+1);
}else{
map.put(ch, 1);
}
}
//Set<Entry<Character, Integer>> set=map.entrySet();
for (Entry<Character, Integer> entry : map.entrySet()) {
char ch=entry.getKey();
int val=entry.getValue();
String str1=ch+"("+val+")";
result.append(str1);
}
System.out.println(result.toString());
}
Array和集合相互转换可以借助Arrays工具类和Collections工具类,Arrays专门操作数组,Collections专门操作集合。
<span style="font-size:14px;">public class CollectionTest {
public static void main(String[] args) {
String[] array = { "111", "222", "333" };
// 数组转集合
List list = Arrays.asList(array);
List<String> arraylist = new ArrayList<String>();
arraylist.add("111");
arraylist.add("222");
arraylist.add("333");
// 集合转数组
array = arraylist.toArray(new String[arraylist.size()]);
// 直接打印数组内容成字符串
System.out.println(Arrays.toString(array));
// 将现有List集合传入比较器实现与TreeSet一样的排序
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
return o1.length() - o2.length();
}
});
System.out.println(list);
//反转排序
Collections.reverse(list);;
System.out.println(list);
}
}</span>