集合主要是用来存放数据的,集合与数组的主要区别在于,集合的大小不受限制,而数组的大小受限制,在使用集合增加数据时又常常与泛型联系起来,所以集合和泛型在实际开发过程中总会结合在一起
数组致命的缺点是数组大小一旦确定,其大小将不在改变,集合可以认为是一种可变的数组,大小可以随着元素的增加而增加。
集合与数组具体的区别:
1.数组是一个线性序列,所以可以快速访问其他元素,当用户创建了一个数组时,其容量是不变的,而且在生命周期也是不能改变的,还有java数组会做边界检查,如果发现有越界现象,会报RuntimeException错误,所以不用担心和CC++一样不做边界检查而出现的问题
2.集合容量是可变的,扩展性比较好
3.集合的内部实现基于数组,所以数组的效率要高于集合
集合两大类:collection集合与map集合
List 结构集合类:
ArrayList类 LinkedList类 Vector类 Stack 类
Map结构集合类: HashMap Hashtable
Set集合类:HashSet TreeSet TreeSet
Queue集合类:Queue接口
1.ArrayList
List集合的子接口,允许集合存储元素可以重复,并可以将null存储在集合中,ArrayList实例都有一个默认容量,该容量用来存储数组元素的大小,并且ArrayList集合的长度可以自动增长
ArrayList是线程不安全的,如果有多个线程同时访问ArrayList,有可能出现访问数据不一致现象,因此使用ArrayList要结合线程加以同步
eg:
1.向ArrayList集合加元素
import java.util.ArrayList; import java.util.List; public class text3 { public static void main(String[] args) { List lis=new ArrayList(); lis.add("张无忌"); lis.add("张无忌"); lis.add("张无忌"); lis.add(520); System.out.println(lis); } }
增加泛型后;
import java.util.ArrayList; import java.util.List; public class text3 { public static void main(String[] args) { List<String> lis = new ArrayList<String>(); //增加内容 lis.add("张无忌"); lis.add("张无忌"); lis.add("张无忌"); lis.add("张无忌"); lis.add("wangzhi"); System.out.println(lis); } }
2.LinkedList
ArrayList 只能在尾部增加而不能在头部增加,LinkedList可以在集合的前后增加,LinkedList是线程不安全的,如果有多个线程同时访问一个链接列表,而其中至少一个线程从结构上修改了该列表,有可能造成集合访问不同步的情况发生
LinkedList增加元素
import java.util.ArrayList; import java.util.List; import java.util.LinkedList; public class text3 { public static void main(String[] args) { LinkedList<String> lis=new LinkedList<String>(); //增加元素 lis.add("张三"); lis.add("李四"); lis.addFirst("王五"); lis.addLast("赵六"); System.out.println(lis); } }
3.HarshSet
该类实现Set接口,并且HashSet的顺序是不确定的,该类允许加入null元素,不允许集合添加重复元素,如果添加重复元素,将会覆盖之前的元素。HashSet是线程不同步的,如果多个线程同时访问一个HashSet,而其中至少一个线程修改了该集合,则可能造成数据访问不一致的情况发生
import java.util.HashSet; import java.util.Set; public class text3 { public static void main(String[] args) { Set<String> set=new HashSet<String>(); //增加元素 set.add("zhangsan"); set.add("lisi"); set.add("wangwu"); set.add("wangwu"); System.out.println(set); } }
4.TreeSet
用来集合元素内部排序使用的,TreeSet 集合是线程不同步的,
import java.util.Comparator; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; public class text3 { public static void main(String[] args) { //创建HashSet TreeSet ts = new TreeSet(); // Add elements to the tree set ts.add("C"); ts.add("A"); ts.add("B"); ts.add("E"); ts.add("F"); ts.add("D"); ts.add("A"); System.out.println(ts); } }
Comparable/comparable接口
主要用来对对象排序使用,这种排序称为自然排序,compareTo方法用户自己定义排序规则
int comparableTo(To) 比较次对象与指定对象的顺序,小于 等于 大于:负整数 0 正整数
实现Comparable接口的实体类:
Person
package text3; /** * 为了更好的实现排序功能,建议比较排序的类实现hashCode和equals方法 * * @author Administrator * */ public class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int hashCode() { final int prime = 31;//注意31 int result = 1; result = prime * result + age; 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; final Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } public String toString() { return name + "," + age; } @Override public int compareTo(Person o) { int c = age - o.age; if (c != 0) return c; return name.compareTo(o.getName()); } // 自动调出 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Test
package text3; import java.util.HashSet; import java.util.Set; public class Text { public static void main(String[] args) { Set<Person> set=new HashSet<Person>(); set.add(new Person("张三丰",20)); set.add(new Person("张无忌",22)); set.add(new Person("刘德华",31)); set.add(new Person("王志",12)); System.out.println(set); } }
增强for循环主要是用来打印集合的,并且增强for循环只能打印数组和泛型的集合,没有增强for循环之前,也可以用for来打印集合
使用for打印
import java.util.Set; import java.util.List; import java.util.ArrayList; import java.util.HashSet; public class Person{ public static void main(String[] args) { printList(); System.out.println("-------------------------------------------"); printSet(); } private static void printSet() { // TODO Auto-generated method stub Set<String> set=new HashSet<String>(); set.add("张无忌"); set.add("张学友"); set.add("王志大帅哥"); Object[] s=set.toArray(); for(int i=0;i<s.length;i++) System.out.println(s[i]); } private static void printList() { // TODO Auto-generated method stub List<String> lis=new ArrayList<String>(); lis.add("张无忌"); lis.add("张学友"); lis.add("谢霆锋"); lis.add("张柏芝"); for(int i=0;i<lis.size();i++) System.out.println(lis.get(i)); } }
使用增强for循环
import java.util.Set; import java.util.List; import java.util.ArrayList; import java.util.HashSet; public class Person{ public static void main(String[] args) { printList(); System.out.println("-------------------------------------------"); printSet(); } private static void printSet() { // TODO Auto-generated method stub Set<String> set=new HashSet<String>(); set.add("张无忌"); set.add("张学友"); set.add("王志大帅哥"); for(String s:set){ System.out.println(s); } } private static void printList() { // TODO Auto-generated method stub List<String> lis=new ArrayList<String>(); lis.add("张无忌"); lis.add("张学友"); lis.add("谢霆锋"); lis.add("张柏芝"); for(String s:lis){ System.out.println(s); } } }
使用增强for循环可以很方便的打印集合,但增强for循环的局限性在于它只能打印集合中的内容,不能对集合本身进行修改,修改后会出现意想不到的情况,会报错
import java.util.Set; import java.util.List; import java.util.ArrayList; import java.util.HashSet; public class Person{ public static void main(String[] args) { printList(); System.out.println("-------------------------------------------"); printSet(); } private static void printSet() { // TODO Auto-generated method stub Set<String> set=new HashSet<String>(); set.add("张无忌"); set.add("张学友"); set.add("王志大帅哥"); for(String s:set){ System.out.println(s); } } private static void printList() { // TODO Auto-generated method stub List<String> lis=new ArrayList<String>(); lis.add("张无忌"); lis.add("张学友"); lis.add("谢霆锋"); lis.add("张柏芝"); for(String s:lis){ System.out.println(s); } } }
而使用普通for循环
package text4; import java.util.List; import java.util.ArrayList; public class Hello { public static void main(String[] args) { delList(); } public static void delList(){ //创建List实例化 List<String> lis=new ArrayList<String>(); //增加内容 lis.add("张无忌"); lis.add("张无忌"); lis.add("刘德华"); //删除 for(int i=0;i<lis.size();i++){ if("张无忌".equals(lis.get(i))){ lis.remove(i); } } //打印 for(String s:lis) System.out.println(s); } }
!!!有两个张无忌但是只删除了一个,解决方案
package text4; import java.util.List; import java.util.ArrayList; public class Hello { public static void main(String[] args) { delList(); } public static void delList(){ //创建List实例化 List<String> lis=new ArrayList<String>(); //增加内容 lis.add("张无忌"); lis.add("张无忌"); lis.add("刘德华"); //删除 for(int i=0;i<lis.size();i++){ if("张无忌".equals(lis.get(i))){ lis.remove(i); i--; } } //打印 for(String s:lis) System.out.println(s); } }
Iterator接口:
使用Iterator遍历集合
package text4; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import java.util.Set; import java.util.HashSet; public class Hello { public static void main(String[] args) { iteratorList(); System.out.println("--------------------------------"); iteratorSet(); } public static void iteratorList() { // 创建实例化 List<String> lis = new ArrayList<String>(); lis.add("张无忌"); lis.add("张无忌"); lis.add("刘德华"); System.out.println("删除前"); System.out.println(); // 获得iterator接口 Iterator<String> it = lis.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); if ("张无忌".equals(s)) { it.remove(); } } System.out.println(); System.out.println("删除后"); // 删除 for (String s : lis) System.out.println(s); } public static void iteratorSet() { // HashSet实例化 Set<String> set = new HashSet<String>(); set.add("张无忌"); set.add("张无忌"); set.add("张三丰"); set.add("刘德华"); // 获得Iterator接口 Iterator it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }
Map接口
基于哈希表的Map接口的实现,Map可以存储键值,并允许使用null值和null键,Map接口不保证映射的顺序,Hashmap是线程不同步的,如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该印射,则它必须保持外部同步,主要用来存储 key_value数据
HashMap增加元素; 可重复当时会覆盖
package text4; import java.util.Map; import java.util.HashMap; public class Hello { public static void main(String[] args) { add(); } public static void add() { Map<String, String> map = new HashMap<String, String>(); // 增加元素 map.put("国家", "中国"); map.put("老公", "小明"); map.put("老婆", "小红"); map.put("身份证", "123456"); // 获取特定key对应的value String id = map.get("身份证"); System.out.println(id); } }
取出map中的所有的key值
package text4; import java.util.Map; import java.util.HashMap; import java.util.Set; //import java.util.keySet; public class Hello { public static void main(String[] args) { add(); } public static void add() { Map<String, String> map = new HashMap<String, String>(); // 增加元素 map.put("国家", "中国"); map.put("老公", "小明"); map.put("老婆", "小红"); map.put("身份证", "123456"); map.put("身份证", "421127199712241714"); // 获取特定key对应的value String id = map.get("身份证"); System.out.println(id); //取出所有的key值 Set<String> keys=map.keySet(); for(String s:keys){ System.out.println(s); } } }
获取集合中所有的value值
package text4; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.Collection; //import java.util.keySet; public class Hello { public static void main(String[] args) { add(); } public static void add() { Map<String, String> map = new HashMap<String, String>(); // 增加元素 map.put("国家", "中国"); map.put("老公", "小明"); map.put("老婆", "小红"); map.put("身份证", "123456"); map.put("身份证", "421127199712241714"); //取出所有的key值 Set<String> keys=map.keySet(); for(String s:keys){ System.out.println(s); } System.out.println("-----------------------------------"); //获取所有的value值 Collection<String> cs=map.values(); for(String s:cs) System.out.println(s); } }
获取所有的key与value值
package text4; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.Collection; //import java.util.keySet; public class Hello { public static void main(String[] args) { add(); } public static void add() { Map<String, String> map = new HashMap<String, String>(); // 增加元素 map.put("国家", "中国"); map.put("老公", "小明"); map.put("老婆", "小红"); map.put("身份证", "123456"); map.put("身份证", "421127199712241714"); System.out.println("获取所有的key值"); //取出所有的key值 Set<String> keys=map.keySet(); for(String s:keys){ System.out.println(s); } System.out.println("-----------------------------------"); System.out.println("获取所有的value值"); //获取所有的value值 Collection<String> cs=map.values(); for(String s:cs) System.out.println(s); System.out.println("------------------------------------"); System.out.println("获取所有的value与key值"); //取出所有的value与key值 Set<Map.Entry<String, String>> sets=map.entrySet(); for(Map.Entry<String, String> s:sets){ String key=s.getKey(); String value=s.getValue(); System.out.println(key+":"+value); } } }
容器选择原则;
综合案例:
A:职员管理系统:
package day4; import java.util.*; import java.io.*; /** * @author qingfeng * 重要思想:面向对象思想(添加员工管理类) * 功能:公司职员薪水管理系统 */ public class SalarySystem { public static void main(String[] args) throws IOException { ClerkManager cm = new ClerkManager();//创建员工管理类 InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); while(true) { //简易菜单 System.out.println("公司职员薪水管理系统"); System.out.println("---------------------------------------"); System.out.println("1.添加新员工"); System.out.println("2.根据工号显示该员工的信息"); System.out.println("3.显示所有员工信息"); System.out.println("4.修改员工的薪水"); System.out.println("5.根据工号删除该员工的信息"); System.out.println("6.根据薪资由低到高排序"); System.out.println("7.统计员工的平均工资、最高工资和最低工资"); System.out.println("---------------------------------------"); System.out.println("请选择序号:"); String no = br.readLine(); if(no.equals("1")){ System.out.println("添加新员工:"); System.out.println("请输入姓名:"); String name = br.readLine(); System.out.println("请输入性别:"); String sex = br.readLine(); System.out.println("请输入年龄:");//如何用InputStreamReader来输入一个int型的数据 Scanner sc = new Scanner(System.in); int age = sc.nextInt(); System.out.println("请输入工号:"); String clerkNo = br.readLine(); System.out.println("请输入薪资:"); float salary = Float.parseFloat(br.readLine()); Clerk clerk = new Clerk(name, sex, age, clerkNo, salary);//创建员工对象并且调用构造方法初始化 cm.addClerk(clerk);//调用“添加新员工”方法 }else if(no.equals("2")){ System.out.println("请输入员工号:"); String clerkNo = br.readLine();//接收输入的工号 cm.showInfo(clerkNo); }else if(no.equals("3")){ System.out.println("显示所有员工信息:"); cm.showAllInfo(); }else if(no.equals("4")){ System.out.println("修改员工的薪水:"); System.out.println("输入员工工号:"); String clerkNo = br.readLine();//接收输入的工号 System.out.println("修改员工薪资:"); String sal = br.readLine(); float salary = Float.parseFloat(sal); cm.modifySal(clerkNo, salary); }else if(no.equals("5")){ System.out.println("根据工号删除该员工的信息:"); System.out.println("输入员工工号:"); String clerkNo = br.readLine();//接收输入的工号 cm.deleteInfo(clerkNo); }else if(no.equals("6")){ System.out.println("根据薪资由低到高排序"); cm.Qsort(0, cm.al.size()-1); cm.showAllInfo(); }else if(no.equals("7")){ System.out.println("统计员工的平均工资、最高工资和最低工资:"); cm.calSalary(); }else if(no.equals("8")){ System.exit(0); }else{ System.out.println("输入不合法!"); } } } } //员工管理类(非常重要!面向对象) class ClerkManager { //成员属性 ArrayList al = null; //构造方法:初始化 不断创造新对象 public ClerkManager() { al = new ArrayList();//注意写法!! } //成员方法 //添加新员工! public void addClerk(Clerk clerk) //注意用增加的对象的引用作为参数! { al.add(clerk); //ArrayList添加方法用add()方法! } //根据工号显示该员工的信息 public void showInfo(String no) { int flag = 0; for(int i=0; i<al.size(); i++) { Clerk clerk= (Clerk)al.get(i); if(clerk.getNo().equals(no)) { flag = 1; System.out.println("clerk"+(i+1)+"的信息是:"); System.out.print("姓名:"+clerk.getName()); System.out.print(" 性别:"+clerk.getSex()); System.out.print(" 年龄:"+clerk.getAge()); System.out.print(" 工号:"+clerk.getNo()); System.out.println(" 薪资:"+clerk.getSalary()); } } if(flag == 0) System.out.println("找不到所查工号!"); } //显示所有员工信息 public void showAllInfo() { for(int i=0; i<al.size(); i++) { Clerk clerk= (Clerk)al.get(i); System.out.println("clerk"+(i+1)+"的信息是:"); System.out.print("姓名:"+clerk.getName()); System.out.print(" 性别:"+clerk.getSex()); System.out.print(" 年龄:"+clerk.getAge()); System.out.print(" 工号:"+clerk.getNo()); System.out.println(" 薪资:"+clerk.getSalary()); } } //修改员工的薪水 public void modifySal(String no, float sal) //员工编号 最新的薪资 { int flag = 0; for(int i=0; i<al.size(); i++) { Clerk clerk= (Clerk)al.get(i); if(clerk.getNo().equals(no)) { flag = 1; clerk.setSalary(sal); } } if(flag == 0) System.out.println("找不到所查工号!"); } //根据工号删除该员工的信息 public void deleteInfo(String no) { int flag = 0; for(int i=0; i<al.size(); i++) { Clerk clerk= (Clerk)al.get(i); if(clerk.getNo().equals(no)) { flag = 1; al.remove(i); } } if(flag == 0) System.out.println("找不到所查工号!"); } //根据薪资由低到高排序 public void Qsort(int left, int right) { int i = left; int j = right; if(i < j)//递归结束条件 { Clerk clerk = (Clerk)al.get(left); float key = clerk.getSalary(); while(i<j)//一趟快速排序 { while(i<j && ((Clerk)al.get(j)).getSalary() >= key) { j--; } if(i<j) { al.set(i,al.get(j)); i++; } while(i<j && ((Clerk)al.get(i)).getSalary() <= key) { i++; } if(i<j) { al.set(j, al.get(i)); } } al.set(i, clerk); Qsort(left, i-1); Qsort(i+1, right); } } //统计员工的平均工资、最高工资和最低工资 public void calSalary() { float totalSal = 0; float minSal = ((Clerk)al.get(0)).getSalary(); float maxSal = ((Clerk)al.get(0)).getSalary(); for(int i=0; i<al.size(); i++) { Clerk clerk = (Clerk)al.get(i); totalSal += clerk.getSalary(); if(minSal > clerk.getSalary()) { minSal = clerk.getSalary(); } if(maxSal < clerk.getSalary()) { maxSal = clerk.getSalary(); } } System.out.println(al.size()+"个人的平均薪资为:" + totalSal/al.size()); System.out.println(al.size()+"个人的最低薪资为:"+minSal); System.out.println(al.size()+"个人的最高薪资为:"+maxSal); } } //员工类 class Clerk { private String name; private String sex; private int age; private String no; private float salary; public Clerk(String name, String sex, int age, String no, float salary) { this.name = name; this.sex = sex; this.age = age; this.no = no; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getNo() { return no; } public void setNo(String no) { this.no = no; } public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } }
B.命令行贪吃蛇