java集合类

本章内容

Collection
List接口及其实现类
泛型
Set接口及其实现类
Iterable
Collections
Comparable
Map
hashCode & equals

问题:一个班级有30名学生,在程序中如何保存这些学生的信息呢?
解决方案:可以在班级类中定义一个数组:
Student students[] = new Student[30];
新的问题:
班级需要增加一名新学生,如何保存?
如何对学生按姓名进行排序?

Collection

Collection对象是将多个元素组成一个单元的对象

集合用于存储、检索和操纵数据

集合框架的优点:
提供有用的数据结构和算法,从而减少编程工作
高性能的数据结构和算法提高了程序速度和质量

这里写图片描述

这里写图片描述

List接口的实现类-ArrayList
ArrayList 对象是长度可变的对象引用数组,类似于动态数组
继承 AbstractList 并实现 List 接口
随着元素的添加,元素的数目会增加,列表也会随着扩展
访问和遍历对象时,它提供更好的性能

这里写图片描述

ArrayList 类的常用方法:
add(Object e) 为列表增加一个新元素
get(int index) 得到下标为index的元素
remove(int index) 删除下标为index的元素
remove(Obiect e) 删除元素e
size() 获得列表的长度

泛型
泛型的使用:
List students = new ArrayList();
students.add(“abc”);//错误,无法通过编译
students.add(new Student()); //正确
Student stu = students.get(0);//不需要强制类型转换

package test2;

public class Student {
	private int id;
	private String name;
	private String password;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Student(){}
	public Student(int id, String name, String password) {
		this.id = id;
		this.name = name;
		this.password = password;
	}
	//重写toString()
	public  String toString(){
		//System.out.println("id="+id+";name="+name);
		return ("id="+id+";name="+name+";password="+password);
	}
	public Student parseStudent(String str){
		Student a=new Student();
		String data[]=str.split("[;]");
		if(data[0]!=null){
			a.id=Integer.parseInt(data[0].substring(data[0].indexOf("=")+1));	

		}
		if(data[1]!=null){
			a.name=(data[1].substring(data[1].indexOf("=")+1));
		}
		if(data[2]!=null){
			a.password=(data[2].substring(data[2].indexOf("=")+1));	
		}
		return a;
	}

}

package test2;

import java.util.ArrayList;
import java.util.List;

public class JiHe {
	public static void main(String[] args) {
		List<Student> list=new ArrayList<Student>();
		Student user1=new Student(1,"jack","pass");
		Student user2=new Student(2,"tom","pass");
		list.add(user1);
		list.add(user2);
		//list.remove(1);
		list.remove(user1);
		for(int i=0;i<list.size();i++){
			System.out.println(list.get(i));//list.get()返回的是一个对象
		}
		
	}
	

}

运行结果:
id=2;name=tom;password=pass

Set接口及其实现类–HashSet

数组、List和Set类型对象遍历方式(for each):
int[] array = new int[]{1, 3, 8};
for(int a: array){ System.out.println(a); }

List list = new ArrayList();
for(Integer i:list){ System.out.println(i); }

Set set = new HashSet();
for(Integer i: set){ System.out.println(i); };

这里写图片描述

这里写图片描述

如何去除list中的重复项呢?
结合使用set可以实现这个功能

  1. Set set = new HashSet(list);//将List类型转化成Set类型
  2. list = new ArrayList(set);//再将Set类型转化成List类型
    打印后面的list会发现顺序与最初不一样,可以使用LinkedHashSet来取代HashSet
List<Student> students = new ArrayList<Student>();
students.add(new Student(“terry”, 10));
students.add(new Student(“lily”, 5));
以下遍历方式:
for(Student stu: students){//…}
相当于:
Iterator<Student> ite = students.iterator();
while(ite.hasNext(){
  Student stu = ite.next();
  //…
}

package test;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class Demo {
	public static void main(String[] args) {
		/*Set<String> set=new HashSet<String>();
		set.add("abc");
		set.add("efg");
		set.add("opg");
		set.add("efg");
		set.remove("opg");
		List<String>list=new ArrayList<String>(set);
		set.removeAll(list);
		for(String ss:set){
			System.out.println(ss);
		}
		/*Iterator<String> str=list.iterator();//迭代器Iterator
		while(str.hasNext()){
			System.out.println(str.next());
		}*/
		List<String> use=new ArrayList<String>();
		use.add("aaa");
		use.add("bbb");
		use.add("aaa");
		use.add("ccc");
		Set<String> se=new LinkedHashSet<String>(use);//将link转换成Set,因为Set无序,LinkedHashSet可以让其有序输出
//		for(String yy:se){
//			System.out.println(yy);
//		}
		for(String yy:se){
			System.out.println(yy);
		}
		//use.removeAll(se);
		/*for(String yy:use){
			System.out.println(yy);
		}*/
	}

}

运行结果:
aaa
bbb
ccc

Collections
Collections提供了对集合类的一些常用操作
如:排序,查找等

两种排序方法:
这里写图片描述

这里写图片描述

package test;
/*User实现了Comparable<User>接口,在CompareTo方法中与其它User进行比较,哪个User大取决于哪个User的姓名的首字母在前*/	

public class User implements Comparable<User>{
	private String name;
	private double score;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	
	public User(String name, double score) {

		this.name = name;
		this.score = score;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", score=" + score + "]";
	}
	@Override
	public int compareTo(User o) {
		/*double a=this.score-o.score;
		if(a>0){
			return 1;
			}
		else if(a==0){
			return 0;
			}
		else{
			return -1;
			}*/
		return this.getName().compareToIgnoreCase(o.getName());
	}
	
	

}

package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TestUser {
	public static void main(String[] args) {
		List<User>list=new ArrayList<User>();
		list.add(new User("jack",88.5));
		list.add(new User("tom",90.7));
		list.add(new User("pary",86.9));
		System.out.println("方式一按照姓名排序如下:");
		Collections.sort(list);//方式一
		for(User str:list){
			System.out.println(str);
		}
		System.out.println("方式二按照成绩排序如下:");
		Collections.sort(list,new Comparator<User>(){
			public int compare(User o1, User o2) {
				//return o1.getName().compareToIgnoreCase(o2.getName()
				double a=o1.getScore()-o2.getScore();
				if(a>0){
					return 1;
					}
				else if(a==0){
					return 0;
					}
				else{
					return -1;
					}
			}
		});//方式二
		for(User str:list){
			System.out.println(str);
		}
	}

}


这里写代码片

运行结果:
方式一按照姓名排序如下:
User [name=jack, score=88.5]
User [name=pary, score=86.9]
User [name=tom, score=90.7]
方式二按照成绩排序如下:
User [name=pary, score=86.9]
User [name=jack, score=88.5]
User [name=tom, score=90.7]

Map
以IP地址存取为例,假定我们需要保存1亿个IP地址对应的用户信息,有如下IPInfo类
class IPInfo{
private String ip;
private String userName;
private String phone;
//省略相关的set/get方法
}

方案1:用List进行保存

List<IPInfo> ips = new ArrayList<IPInfo>(100000000);//ips.size()依然为0
//将IPInfo对象加入到列表中,省略。

如果有一个IP为192.168.1.110的用户访问了系统,如何获取对应的IPInfo呢?
for(IPInfo ip: ips){
  if(ip.getIP().equals(“192.168.1.110”)){
    //得到IPInfo对象
  }
}

以上的查询方式确实可以找到我们需要的结果,然而要循环很多次,效率低。

方案二:使用Map
这里写图片描述

HashMap:
实现了 Map 接口

用于存储键/值映射关系

不能保证其元素的存储顺序

这里写图片描述

这里写图片描述

HashMap的遍历

package test3;

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

/**
 * Map的三种遍历方式
 * @author Administrator
 *
 */
public class Demo {
	public static void main(String[] args) {
		Map<Integer,Student> map=new HashMap<Integer,Student>();
		map.put(1,new Student(1,"张飞"));
		map.put(2,new Student(2,"孙杨"));
		map.put(3,new Student(3,"陈云"));
		map.put(4,new Student(4,"李官"));
		System.out.println("第一种:通过Map.keySet遍历key和value:");
		Set<Integer> set=map.keySet();
		for(Integer sc:set){
			System.out.println(map.get(sc));
		}
		System.out.println("第二种:通过Map.entrySet使用iterator遍历key和value:");
		Iterator<Map.Entry<Integer, Student>> it = map.entrySet().iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
		System.out.println("第三种:通过Map.entrySet遍历key和value");
		for (Map.Entry<Integer,Student> entry : map.entrySet()) {
			System.out.println(entry);
		}
		 
	}

}

运行结果:
第一种:通过Map.keySet遍历key和value:
Student [id=1, name=张飞]
Student [id=2, name=孙杨]
Student [id=3, name=陈云]
Student [id=4, name=李官]
第二种:通过Map.entrySet使用iterator遍历key和value:
1=Student [id=1, name=张飞]
2=Student [id=2, name=孙杨]
3=Student [id=3, name=陈云]
4=Student [id=4, name=李官]
第三种:通过Map.entrySet遍历key和value
1=Student [id=1, name=张飞]
2=Student [id=2, name=孙杨]
3=Student [id=3, name=陈云]
4=Student [id=4, name=李官]

package test;

public class IPInfo {
	private String ip;
	private String name;
	private String phone;
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public IPInfo(String ip, String name, String phone) {
		super();
		this.ip = ip;
		this.name = name;
		this.phone = phone;
	}
	@Override
	public String toString() {
		return "IPInfo [ip=" + ip + ", name=" + name + ", phone=" + phone + "]";
	}
	

}

package test;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class MU {
	public static void main(String[] args) {
		Map<String,IPInfo> ss=new HashMap<String,IPInfo>(1000);
		ss.put("192.168.8.7",new IPInfo("192.168.8.7","jack","190842355"));
		ss.put("192.168.8.4",new IPInfo("192.168.8.4","tom","1415645566"));
		ss.put("192.168.8.5",new IPInfo("192.168.8.5","mack","141265679"));
		System.out.println("请输入要查找的ip:");
		String in=new Scanner(System.in).nextLine();
		System.out.println(ss.get(in));
		
		
	}
	
	

}

运行结果:
请输入要查找的ip:
192.168.8.4
IPInfo [ip=192.168.8.4, name=tom, phone=1415645566]

//获取HashMap中键所对应的值

package test;

public class A {
	private int m=0;
	public A(int m){
		this.m=m;
	}
	public int getM(){
		return m;
	}
	@Override
	public String toString() {
		return "A [m=" + m + "]";
	}
	

}

package test;

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

public class TestA {
	public static void main(String[] args) {
		Map<String,A> map=new HashMap<String,A>();
		int tmp=0;
		for(int i=0;i<4;i++){
			tmp=(int)(Math.random()*100);
			map.put("00"+i,new A(tmp));
		}
		Set<String>set=map.keySet();//将map中的键Set化,以便遍历
		for(String ss:set){
			System.out.println(map.get(ss));
			A a = (A)map.get(ss);
			System.out.println(a.getM());
		}

	}

}

运行结果:
A [m=15]
15
A [m=53]
53
A [m=40]
40
A [m=20]
20

hashCode & equals
重写A中的hashCode,重新检查前面set的长度
pubilc int hashCode(){
return id;
}
重写A中的equals,重新检查前面set的长度
public boolean equals(Object o){
if(!(o instanceof A)){return false;}
return id == ((A)o).id;
}

将一个新的对象add到HashSet中时,程序将结合hashCode和equals两个方法来判断元素是否重复,如果重复,则用新的对象替代老的对象,若不重复,则将新的对象add到set中。

将一个新的key-value对put到HashMap中时,程序将检测key是否重复,原理同上。
总结:类型转换,list转换为set可以用new LinkedHashSet(list),map转换成set可以用
keySet()和entrySet()。

发布了90 篇原创文章 · 获赞 33 · 访问量 12万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览