Java中的集合学习笔记

最近一直在看Java里的集合这块,初看觉得内容不多,细看之后发现东西真的很多。我的学习也还只是停留在初级阶段,这边我想做一个大概的整理。


这个是集合的大致分类,我只学习了一般用到的一些集合,其他更详细的暂时还没有学习。


首先,以下的程序基本上都用到了这个Student类,所以放在最上面贴出来。

package hashmap20160107;

public class Student /*implements Comparable<Student>*/{
	
	private String name;
	private Integer age;

	Student(String name, Integer age){
		this.setName(name);
		this.setAge(age);
	};
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public Integer getAge(){
		return age;
	}
	
	public void setAge(int age){
		this.age = age;
	}
	
	
	
	 /*public int compareTo(Student arg0) {
		 
	        return this.getAge().compareTo(arg0.getAge());
	        //这边返回的是一个int型的数据
	 }
	
	public boolean equals(Object o){
		   if(this == o){
		    return true;
		   }
		   if(! (o instanceof Student)){
		    return false;
		   }
		   final Student other = (Student)o;
		   if(this.name.equals(other.getName()) && this.age.equals(other.getAge())){
		    return true;
		   }
		   else{
		    return false;
		   }
		}

		public int hashCode(){
		   int result;
		   result = (name == null?0:name.hashCode());
		   result = 37*result + (age == null?0:age.hashCode());
		   return result;
		}
		*/
}

这边因为下面的集合有的要实现comparable接口,有的要重写equals和hashcode方法,所以都放了进去。

1、ArrayList(按顺序存储可重复)

这个程序没有用到实体类里的任何方法
package Arraylist20151203;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;

/**
 * 
 * http://jingyan.baidu.com/article/5bbb5a1b1f4c7613eba1790d.html 百度经验
 *
 */
public class test2 {
	
	public void run(){//整形数组
		
		ArrayList<int[]> list = new ArrayList<int[]>();
		int[] nums = {0,1,2,3,4};
		list.add(nums);
		Iterator<int[]> iterators = list.iterator();
	    //循环迭代器
	    while (iterators.hasNext()) {        //如果有下一个值,进入循环
	            int[] result = iterators.next();        //得到迭代器中下一个值 返回String类型
	            for(int i = 0;i<result.length;i++){
	            	System.out.println(result[i]);//输出结果
	            }
	            
	    }
	}
	
	public void run2(){//插入字符串中
		ArrayList<String> list2 = new ArrayList<String>();
		list2.add("我是第一个对象");
	    list2.add("我是第二个对象");
	    list2.add("我是第三个对象");
	    list2.add("我是第四个对象");
	    list2.add("我是第五个对象");
	    list2.add(1,"我是插入的对象");//在第一个对象后面插入
	    
	    Iterator<String> i = list2.iterator();
	    while(i.hasNext()){
	    	String s = i.next();
	    	System.out.println(s);
	    }
	}

	public void run3(){//全部插入
		
		ArrayList<String> list3 = new ArrayList<String>();
		list3.add("我是第一个对象");
	    list3.add("我是第二个对象");
	    list3.add("我是第三个对象");
	    ArrayList<String> list4 = new ArrayList<String>();
	    list4.add("我是插入的对象");
	    list4.addAll(list3);//在前面插入
	    
	    Iterator<String> i = list4.iterator();
	    while(i.hasNext()){
	    	String s = i.next();
	    	System.out.println(s);
	    }
	    
	}
	
	public void run4(){//全部插入
		
		ArrayList<String> list5 = new ArrayList<String>();
		list5.add("我是第一个对象");
	    list5.add("我是第二个对象");
	    list5.add("我是第三个对象");
	    list5.add("我是第四个对象");
	    ArrayList<String> list6 = new ArrayList<String>();
	    list6.add("我是第一个对象");
	    list6.add("我是第二个对象");
	    
	    /*
	     * 下面做了增删改三个功能,可以都试一下体会一下
	     */
	    
	    //list5.addAll(0,list6);//可以指定位置插入对象,允许重复
	    //list5.removeAll(list6);//删除对象
	    //list5.set(0,"我是改变的对象");//可以改变对象的值
	        
	    Iterator<String> i = list5.iterator();
	    while(i.hasNext()){
	    	String s = i.next();
	    	System.out.println("清空之前 "+s);
	    }
	    
	    String ele = list5.get(1);
	    System.out.println("获得的单条数据 "+ele);//从0开始计数
	    list5.clear();
    	System.out.println("清空之后 "+list5);
	    
	}
	
	
	public static void main(String[] args){
		
		test2 t = new test2();
		boolean flag = false;
		do{
			System.out.println("请选择执行第几个程序,如果想要终止,请输入N");
			Scanner scan = new Scanner(System.in);
			String ss = scan.next();
			if(ss.equals("N")){
				flag = false;
				System.out.println("END!");
				break;
			}
			switch(ss){
			case "1": 
				t.run();
				break;
			case "2": 
				t.run2();
				break;
			case "3": 
				t.run3();
				break;
			case "4": 
				t.run4();
				break;
			}
		}while(flag = true);
	}
}

因为ArrayList比较基础,所以这边我没有将对象添加到里面去,而是做了一些基本的功能,以后其他的集合都可以用来参照。


2、LinkedList(链式存储可重复)

这个程序没有用到实体类里的任何方法

以下实现的功能是按姓名和年龄进行排序
package LinkedList20151204;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;

public class linkedlist extends Student{
	linkedlist(String name, int age) {
		super(name, age);
		// TODO 自动生成的构造函数存根
	}

	public static void main(String[] args) {

		Student a = new Student("a", 21);
		Student b = new Student("e", 22);
		Student c = new Student("c", 11);
		Student d = new Student("d", 19);

		LinkedList<Student> studentList = new LinkedList<Student>();
		studentList.add(a);
		studentList.add(b);
		studentList.add(c);
		studentList.add(d);

		System.out.println("-------按年纪排序--------");
		Collections.sort(studentList, new SortByAge());
		for (Student student : studentList) {
			System.out.println(student.getName() + " / " + student.getAge());
		}
		
		System.out.println("-------按姓名排序--------");
		Collections.sort(studentList, new SortByName());
		for (Student student : studentList) {
			System.out.println(student.getName() + " / " + student.getAge());
		}
	}
}

class SortByAge implements Comparator<Student> {
	
	public int compare(Student o1, Student o2) {
		  return (o2.getAge() -o1.getAge() ); 
		}
}

class SortByName implements Comparator<Student> {
	
	public int compare(Student o1, Student o2) {
		return o1.getName().compareTo(o2.getName());
	}
}

/*
 *  Comparable & Comparator 都是用来实现集合中元素的比较、排序的
 *  只是 Comparable 是在集合内部定义的方法实现的排序
 *  Comparator 是在集合外部实现的排序
 *  所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。
 */

这边做了两个排序,像list接口里的集合好像都是要自己写排序的方法。实现Collections.Sort就可以了,还是比较方便的。

3、HashSet(无序,元素不可重复)

这个程序用到了实体类中的hashcode和equals

以下实现的功能是通过实现重写hashcode和equals来进行排序
package hashset20151216;

import java.util.HashSet;
import java.util.Iterator;

public class hashset extends Student{
	hashset(String name, Integer age) {
		super(name, age);
		// TODO 自动生成的构造函数存根
	}
	
	/*
	 * 在实体类Student里重写了equals和hashcode可以实现去除重复元素的功能。
	 * 
	 * 结论:如将自定义类用hashSet来添加对象,一定要覆盖hashcode()和equals()
	 * 覆盖的原则是保证当两个对象hashcode返回相同的整数,而且equals()返回值为True。
	 */

	public static void main(String[] args) {

		Student a = new Student("e",23);
		Student b = new Student("c",21);
		Student c = new Student("d",22);
		Student d = new Student("c",21);
		

		HashSet<Student> studentList = new HashSet<Student>();
		studentList.add(a);
		studentList.add(b);
		studentList.add(c);
		studentList.add(d);
		

		Iterator<Student> iterators = studentList.iterator();
		while(iterators.hasNext()){
			Student result = iterators.next();
			System.out.println(result.getName()+" "+result.getAge());   
		}
		
	}
}

虽然现在大部分的JDK都已经要求覆盖了hashcode,但如果使用自定义类进行添加的话,偷懒而没有设定equals(),就会造成返回的hashcode虽然结果相同,但在程序执行时会多次调用equals,从而影响程序执行的效率。

我们要保证相同对象返回的hashcode一定相同,但也要保证不同对象的hashcode尽可能不同。

4、TreeSet(无序,元素不可重复)

这个程序用到了实体类中的compareTo()方法

以下程序实现的是按年龄进行排序

package TreeSet20160107;

import java.util.Iterator;
import java.util.TreeSet;

public class treeset extends Student{
	
	treeset(String name, Integer age) {
		super(name, age);
		// TODO 自动生成的构造函数存根
	}
	
	public static void main(String[] args) {
		
		Student a = new Student("a",23);
		Student b = new Student("b",21);
		Student c = new Student("c",21);
		Student d = new Student("d",24);
		
		TreeSet<Student> studentlist = new TreeSet<Student>();
		studentlist.add(a);
		studentlist.add(b);
		studentlist.add(c);
		studentlist.add(d);
		
		Iterator<Student> iterators = studentlist.iterator();
		while(iterators.hasNext())
		{
			Student result = iterators.next();
			System.out.println(result.getName()+" "+result.getAge());
		}
		<pre name="code" class="java">package hashmap20160107;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

public class hashmap extends Student{

	hashmap(String name, Integer age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args){

		Student a = new Student("a",23);
		Student b = new Student("b",21);
		Student c = new Student("c",22);
		Student d = new Student("d",21);
		
		Map<String,Student> studentlist=new HashMap<String,Student>();
		studentlist.put("1",a);
		studentlist.put("2",b);
		studentlist.put("3",c);
		studentlist.put("4",d);
		
		/**
		 * 方法一遍历map,推荐使用该方法遍历map集合,尤其是容量大时
		 * 
		 * entry用来迭代map
		 * keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry。
		 * Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry。它表示Map中的一个实体(一个key-value对)。
		 * 接口中有getKey(),getValue方法。
		 */
		for(Map.Entry<String, Student> entry : studentlist.entrySet()){
			System.out.println(entry.getKey()+"="+entry.getValue().getName()+" "+entry.getValue().getAge());
		}
		
		System.out.println("**********************");
		
		/**
		 * 方法二遍历map
		 */
		Set<Entry<String, Student>> entrySet = studentlist.entrySet();
		
		for(Iterator<Map.Entry<String, Student>> iterator = entrySet.iterator();iterator.hasNext();){
			Map.Entry<String, Student> entry = iterator.next();
			
			System.out.println(entry.getKey()+"="+entry.getValue().getName()+" "+entry.getValue().getAge());
		}
	}
}

}}/* * 当要比较的元素相同时,treeset就会去除相同的元素,从而删除整个对象,但其实对象并不相同啊。这里很奇怪。 */
 这边要给TreeSet实现排序还是比较简单的,但是为什么会根据一个相同的属性去除明明是两个不同的对象,我就不是很明白了。 
 
在CSDN上查找了一下,发现@ qybao 的解释 但 TreeSet 实例使用它的 compareTo(或 compare)方法对所有元素进行比较,因此从 set 的观点来看,此方法认为相等的两个元素就是相等的。
原帖: http://bbs.csdn.net/topics/380106821 【TreeSet判断元素重复的问题】

5、HashMap(无序,不可重复)

这个程序没有用到实体类中的任何方法,实现的功能为按age排序

package hashmap20160107;

import java.util.*;
import java.util.Map.Entry;

public class hashmap extends Student{

	hashmap(String name, Integer age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args){

		Student a = new Student("a",23);
		Student b = new Student("b",21);
		Student c = new Student("c",22);
		Student d = new Student("d",21);
		
		Map<String,Student> studentlist=new HashMap<String,Student>();
		studentlist.put("1",a);
		studentlist.put("2",b);
		studentlist.put("3",c);
		studentlist.put("4",d);
		
		List<Map.Entry<String, Student>> studentlist2 = new ArrayList<Map.Entry<String, Student>>(studentlist.entrySet());
	    Collections.sort(studentlist2, new Comparator<Map.Entry<String, Student>>()  
	      {   
	    	public int compare(Map.Entry<String, Student> o1, Map.Entry<String, Student> o2)  
	    	{ 

	    		if(o2.getValue().getAge().compareTo(o1.getValue().getAge())>0){  
	    			return 1;  
	    		}
	    		else{ 
	    			return -1;  
	    		}  

	    	}  
	      }); 
	    //参考http://blog.csdn.net/fly_fish456/article/details/8204298
	    
	    Iterator<Map.Entry<String, Student>> it = studentlist2.iterator();
	    while(it.hasNext())
	    {
	    	Map.Entry<String,Student> entry =(Map.Entry) it.next();  
	    	String name = entry.getValue().getName();
			int age = entry.getValue().getAge();
			System.out.println(name+" "+age);
	    }
		/**
		 * 方法一遍历map,推荐使用该方法遍历map集合,尤其是容量大时
		 * 
		 * entry用来迭代map
		 * keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry。
		 * Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry。它表示Map中的一个实体(一个key-value对)。
		 * 接口中有getKey(),getValue方法。
		 */
	    
	    /*
		for(Map.Entry<String, Student> entry : studentlist.entrySet()){
			System.out.println(entry.getKey()+"="+entry.getValue().getName()+" "+entry.getValue().getAge());
		}
		
		System.out.println("**********************");
		
		
		//方法二遍历map
		 
		Set<Entry<String, Student>> entrySet = studentlist.entrySet();
		
		for(Iterator<Map.Entry<String, Student>> iterator = entrySet.iterator();iterator.hasNext();){
			Map.Entry<String, Student> entry = iterator.next();
			
			System.out.println(entry.getKey()+"="+entry.getValue().getName()+" "+entry.getValue().getAge());
		}
		*/
		
	}
}

这里做了一个按年龄排序的功能。HashMap里按照Key值进行排序很好做,但是按照Value值排序真的很难做,我在网上查找了大量的资料才写出了上面这个不是很完美的程序。
而且其实也算是稀里糊涂的改来改去发现就可以了。。。只能在以后遇到更实际的问题时再做研究了。
然后注释的部分是在没有实现排序的情况下做的两种遍历的方法,map的遍历也是很有趣,有很多种的遍历。

注:在实现查询的时候,如果是使用的是SET,那么必须全部遍历,所以效率比较低。而map因为采取的是KEY-VALUE对应的形式,所以查询的效率比较高。
注意:HashMap与HashCode有关,用Sort对象排序。
如果在HashMap中有key值重复,那么后面一条记录的value覆盖前面一条记录。

6、TreeMap(有序,不可重复)

这个程序没有用到实体类的任何方法,实现的功能为排序

package treemap20160111;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

public class treemap extends Student{

	treemap(String name, Integer age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) {
		
		Student a = new Student("a",23);
		Student b = new Student("b",21);
		Student c = new Student("c",22);
		Student d = new Student("d",21);
		
		TreeMap<String, Student> studentlist = new TreeMap<String,Student>(new Comparator<String>(){
			
			public int compare(String o1, String o2) {
				
				//指定排序器按照降序排列
				return o2.compareTo(o1);
			}
			
		});
		
		/*
		 * TreeMap默认按照key值进行升序排序
		 * 如果指定排序器则可以实现按key值降序排序
		 */
		studentlist.put("1",a);
		studentlist.put("2",b);
		studentlist.put("5",c);
		studentlist.put("4",d);
		
		//TreeMap遍历的两种方法 http://remind.iteye.com/blog/228073
		Iterator it = studentlist.entrySet().iterator();
		while(it.hasNext())
		{
			Map.Entry<String,Student> entry =(Map.Entry) it.next();  
			String name = entry.getValue().getName();
			int age = entry.getValue().getAge();
			System.out.println(name+" "+age);
		}
	}
}

因为TreeMap本来就自带按KEY值降序排序的功能,所以还是比较好的,当然也可以就指定比较器,将之按降序排序。

7、总结

各个集合都有自己的优缺点吧,自然是要根据具体的情况来选择集合,考验功力的时候到了。
不过我们有这么多的前辈已经给我总结了大概的使用效率。


集合中常用的是:ArrayList,HashSet,HashMap。其中ArrayList和HashMap使用最为广泛。

常用自然是因为效率高。
ArrayList VS LinkedList   ArrayList是以数组的形式保存的,所以插入删除都很麻烦,但是查询效率高。LinkedList是以链式存储的,插入删除简单,查询麻烦。
HashSet VS TreeSet       HashSet非常的消耗空间,TreeSet因为有排序功能,因此资源消耗非常的高,我们应该尽量少使用,而且最好不要重复使用。除非必须排序,不然使用HashSet。
HashMap VS TreeMap   一般使用HashMap,排序的时候使用TreeMap。

8、添加知识点:

集合对象存放的是一系列对象的引用。
例:
Student S
Al.add(s);
s.setName(“lucy”);
Student s2=(Student)(al.get(o1));
可知s2也是s。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值