Java集合--简单讲解
来源:互联网 发布:淘宝试用报告草稿在哪 编辑:程序博客网 时间:2024/05/22 06:11
- 数组与集合
- 集合整体结构图
- Collection和Iterator
- List接口
- List示例-String类型
- 遍历集合的方法
- Iterator迭代器
- forEach循环
- 泛型的初步
- 为什么使用泛型
- 使用泛型解决示例
- List示例-Student类型
- List排序
- List自定义排序
- Comparator示例
- Camparable和Comparator
- 面试题
- Set接口
- 哈希表
- HashSet
- HashSet 怎样存储对象
- TreeSet
- Map接口
- HashMap
- Map的遍历
- TreeMap
- HashMap与Hashtable
- Collections工具类
- List接口
数组与集合
- 在创建Java数组时,数组的长度必需要指定,数组一旦创建好之后,长度不改变,在同一个数组中只能存放同一种类型的数据(基本类型和引用类型)
- 为了使程序能方便的存储和操作数目不固定的一组数据,JDK类库中提供了Java集合,所有的Java集合都在java.util包中,在集合中,只能存放对象的引用,而不能存放基本数据类型
- Java集合主要有3种重要的类型:
- List:是一个有序集合,可以存放重复的数据;
- Set:是一个无序集合,不允许存放重复的数据;
- Map:是一个无序集合,集合中包含一个键对象,一个值对象,键对象不允许重复,值对象可以重复(身份证号码–姓名)
集合整体结构图
Collection和Iterator
- Collection是List和Set的父接口,在Collection中定义了一些主要方法
List接口
- List接口是一个有序集合,可以放入重复数据;
- 下面主要有两个实现:ArrayList和LinkedList,他们都是有顺序的,也就是放进去是什么顺序,取出来还是什么顺序,也就是基于线性存储,可以看作是一个可变的数组
- ArrayList:查询数据比较快,添加和删除数据比较慢(基于可变数组)
- LinkedList:查询数据比较慢,添加和删除数据比较快(基于链表数据结构)
- Vector:Vector已经不建议使用,Vector中的方法都是同步的,效率慢,已经被ArrayList取代
List示例-String类型
public class Test01 { public static void main(String[] args) { String s1= new String("zhangsan"); String s2= new String("lisi"); String s3= new String("wangwu"); List l = new ArrayList(); l.add(s1); l.add(s2); l.add(s3); l.remove(1);// System.out.println(l.size());// System.out.println(l.contains(s2));// System.out.println(l.get(0));// System.out.println(l.get(1));// for (int i = 0; i < l.size(); i++) {// System.out.println(l.get(i));// } Iterator it = l.iterator(); //迭代器 while(it.hasNext()){ String s =(String) it.next(); System.out.println(s); } }}
遍历集合的方法
Iterator迭代器
Iterator<E> i = list.iterator(); public boolean hasNext(); public E next();
forEach循环
泛型的初步
泛型能更早的发现错误,如类型转换错误,通常在运行期才会发现,如果使用泛型,那么在编译器将会发现,通常错误发现的越早,越容易调试,越容易减少成本
为什么使用泛型
import java.util.*; public class GenericTest01 { public static void main(String[] args) { List l = new ArrayList(); l.add(1); l.add(2); l.add(3); for (Iterator iter=l.iterator(); iter.hasNext();) { //出现了java.lang.ClassCastException异常 //这种转型错误在运行期被发现了 //错误发现的越早越好,最好在编译器能发现类似的错误 //如果想在编译器发现类似的错误,必须使用泛型 String s = (String)iter.next(); System.out.println(s); } } }
使用泛型解决示例
import java.util.*; public class GenericTest02 { public static void main(String[] args) { List<Integer> l = new ArrayList<Integer>(); l.add(1); l.add(2); l.add(3); //不能将abc放到集合中,因为使用泛型,在编译器就可以返现错误 //l.add("abc"); for (Iterator<Integer> iter=l.iterator(); iter.hasNext();) { //因为使用泛型,在编译器就可以发现错误 //String s = (String)iter.next(); //使用泛型可以不用进行强制转换 //Integer s = (Integer)iter.next(); //可以直接取得相应的元素,使用泛型返回的是真正的类型 Integer s = iter.next(); System.out.println(s); } } }
List示例-Student类型
class Student { String no; String name; int age; public Student(String no,String name, int age) { this.no = no; this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (no == null) { if (other.no != null) return false; } else if (!no.equals(other.no)) return false; return true; } } public class Test { public static void main(String[] args) { Student s1 = new Student("001","zs", 15); Student s2 = new Student("002","ls", 15); Student s3 = new Student("003","ww", 15); Student s4 = new Student("003","ww", 15); List l = new ArrayList(); l.add(s1); l.add(s2); l.add(s3); //针对对象类型,如果要使用contains方法,必须要重写equals // if(!l.contains(s4)){ // l.add(s4); // } // // System.out.println(l.size()); // for (Object o : l) { // Student s = (Student)o; // System.out.println(s.name); // } // // System.out.println(l.contains(s4)); Iterator it = l.iterator(); while(it.hasNext()){ Student s = (Student)it.next(); System.out.println(s.name+":"+s.age); } } }
List排序
void Collections.sort(List);
String person1 = "zhang3"; String person2 = "li4"; String person3 = "wang5"; List<String> list = new ArrayList<>(); list.add(person1); list.add(person2); list.add(person3); Collections.sort(list); Iterator<String> it = list.iterator(); while(it.hasNext()) { System.out.println(it.next());}
Student stu1=new Student("zhang2",20); Student stu2=new Student("zhang1",10); Student stu3=new Student("zhang1",30); List<Student> list1=new ArrayList<Student>(); list1.add(stu1); list1.add(stu2); list1.add(stu3); //由于没有实现Comparable接口,无法通过编译 Collections.sort(list); Iterator<Student> it=list.iterator(); while(it.hasNext()){ Student student=it.next(); System.out.println(student.getName()); }
- String+8种包装类默认已经实现了Comparable接口
先按年龄排序,再按序号
Student s = (Student)o; int i = this.age - s.age; if(i==0){ return this.no.compareTo(s.no); } return i;
List自定义排序
- Collection类的sort方法有个重载方法:sort(Listlist,Comparator
Comparator示例
- 可以通过实现Comparator自定义排序规则
Camparable和Comparator
- 一个类实现了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序,如果集合中使用比较功能,必须保证集合中的数据类型是一致的。
- Comparator可以看成一种算法的实现,将算法和数据分离,Comparator也可以在下面两种环境下使用:
- 1.类没有考虑到比较问题而没有实现Comparable,可以通过Comparator来实现排序而不必改变对象本身
- 2.可以使用多种排序标准,比如升序、降序等
面试题
Set接口
- Set:是一个无序集合,不允许放重复的数据,主要有两个实现类–HashSet和TreeSet
哈希表
- 哈希表是一种数据结构,哈希表能够提供快速存取操作。哈希表是基于数组的,所以也存在缺点,数组一旦创建将不能扩展
- 正常的数组,如果需要查询某个值,需要对数组进行遍历,只是一种线性查找,查找的速度比较慢,如果数组中的元素值和下标能够存在明确的对应关系,那么通过数组元素的值就可以换算出数组元素的下标,通过下标就可以快速定位数组元素,这样的数组就是哈希表。一张哈希表:
HashSet
HashSet中的数据是无序的不可重复的。HashSet按照哈希算法存取数据的,具有非常好的性能,它的工作原理是这样的:当向HashSet中插入数据的时候,他会调用对象的hashCode得到该对象的哈希码,然后根据哈希码计算出该对象插入到集合中的位置
String person1=”zhang3”;
String person2=”li4”;
String person3=”wang5”;Set<String> set1=new HashSet<String>();set1.add(person1);set1.add(person2);set1.add(person3);Iterator<String> it=set1.iterator();while(it.hasNext()){ System.out.println(it.next());//输出是没有顺序的}
HashSet 元素不可重复
String person1="zhang3";String person2="li4";String person3="wang5";String person3="wang5";Set<String> set1=new HashSet<String>();set1.add(person1);set1.add(person2);set1.add(person3);set1.add(person4);Iterator<String> it=set1.iterator();while(it.hasNext()){ System.out.println(it.next());}zhang3wang5li4
HashSet 没有成功的去除重复元素
Student stu1=new Student(“zhang2",20);Student stu2=new Student("zhang1",10);Student stu3=new Student("zhang3",30);Student stu4=new Student("zhang3",30);Set<Student> set2=new HashSet<Student>();set2.add(stu1);set2.add(stu2);set2.add(stu3);set2.add(stu4);Iterator<Student> it=set2.iterator();while(it.hasNext()){ Student student=it.next(); System.out.println(student.getName());;}
是重写了Student的equals方法
public class Student1 implements Comparable<Student>{ String name; int age; @Override public boolean equals(Object obj){ System.out.println("equals方法被调用"); if(this==obj) return true; if(obj==null) return false; if(getClass()!=obj.getClass()) return false; Student1 other=(Student1)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; }}
HashSet 仍然没有成功的去除重复元素,且equals没有调用
Student stu1=new Student("sun2",20);Student stu2=new Student("sun1",10);Student stu3=new Student("sun3",30);Student stu4=new Student("sun3",30);Set<Student> set2=new HashSet<Student>();set2.add(stu1);set2.add(stu2);set2.add(stu3);set2.add(stu4);Iterator<Student> it=set2.iterator();while(it.hasNext()){ Student student=it.next(); System.out.println(student.getName());;}
采取HashSet存储对象类型数据,除了重写equals(),还必须要重写了hashCode方法后
@Overridepublic int hashCode() { System.out.println("hashCode方法被调用了"); final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result;}
HashSet 怎样存储对象
- Object中定义了 publicinthashCode()
- HashSet怎样存储对象
- 调用hashCode()
- 当发现两个对象hashCode值相同时,再调用equals
- HashCode方法的覆盖建议
- 内容相同的对象,hashCode值一样
- 最佳实践:不要自己提供hashCode值得算法,二是使用IDE自动生成,这是hashCode数学专家提供的算法,更可靠
- hashCode和equals方法最好成对重写,不要只重写一个
TreeSet
- SortedSet接口的实现类
- 可以排序
- 必须:元素实现Comparable接口;或调用TreeSet(Comparator
Map接口
- 常用方法
- key不可以重复、value可以重复
- put(K key,Vvalue);
- get(Object key);
- remove(Object key);
- clear();
- isEmpty();
- size();
HashMap
HashMap的常规使用
Map<String,String> map=new HashMap<>();map.put("key1","value1");map.put("key2","value2");map.put("key3","value2");map.put("key1","value4");//替换了第一次放入的value1System.out.println(map.get(“key1”));//value4System.out.println(map.get("key2")); //value2System.out.println(map.get("key3")); //value2System.out.println(map.get(“key8”));//null
- HashMap的key也是通过Hash算法 过滤重复
- Map的key一般都应用String
- 如果想用自己写的类作为key值,那么就必须重写hashCode()方法和equals()方法,而且要保证对象不可变,也就是和String一样,一旦创建了这个对象,就不可修改。
Map的遍历
值遍历
Map<String,String> map=new HashMap<>();map.put("key1","value1");map.put("key2","value2");map.put("key3","value2");map.put("key1","value4");//替换了第一次放入的value1Collection<String> collection=map.values();for(String str:collection){ System.out.println(str);}/** value2* value2* value4*/
键遍历
Map<String,String> map=new HashMap<String,String>();map.put("key1","value1");map.put("key2","value2");map.put("key3","value2");map.put("key1","value4");//替换了第一次放入的value1Set<String> set=map.keySet();for(String str:set){ System.out.println(str);} /* * key3 * key2 * key1 */
键值遍历一
Map<String,String> map=new HashMap<String,String>();map.put("key1","value1");map.put("key2","value2");map.put("key3","value2");map.put("key1","value4");//替换了第一次放入的value1Set<String> set=map.keySet();for(String key:set){ System.out.println(key+":"+map.get(key));} /* * key3:value2 * key2:value2 * key1:value4 */
键值遍历二
Entry是Map接口的一个内部接口,即子接口。 先有Map集合再有映射关系,是Map集合的内部事务 Map.Entry中存的是映射关系这种数据类型。
Map<String,String> map=new HashMap<String,String>(); map.put("key1","value1"); map.put("key2","value2"); map.put("key3","value2"); map.put("key1","value4");//替换了第一次放入的value1 Set<String> set=map.keySet(); for(Entry<String,String> entry:map.entrySet()){ System.out.println(entry.getKey()+":"+entry.getValue()); } /* * key3:value2 * key2:value2 * key1:value4 */
TreeMap
TreeMap 可以对key应用排序
Map<String,String> map1=new TreeMap<String,String>();map1.put("b", "value1");map1.put("d", "value2");map1.put("c", "value2");map1.put("a", "value4");for(Entry<String,String> entry:map.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());} /* * a:value4 * b:value1 * c:value2 * d:value2 */
TreeMap的key是通过Comparable接口 过滤重复 排序,也可以通过Comparator接口的实现类的对象来过滤重复排序
- Map的key一般都应用String多
HashMap与Hashtable
- Hashtable 与 HashMap的区别
Collections工具类
Collections位于java.util包中,提供了一系列实用的方法,如:对集合排序,对集合中的内容查找等
import java.util.*;public class CollectionsTest01 { public static void main(String[] args) { List l = new ArrayList(); l.add(5); l.add(1); l.add(4); l.add(2); for (Iterator iter=l.iterator(); iter.hasNext();) { System.out.println(iter.next()); } System.out.println(“—List排序---"); Collections.sort(l); for (Iterator iter=l.iterator(); iter.hasNext();) { System.out.println(iter.next()); } System.out.println("-----"); Set set = new HashSet(); set.add(10); set.add(1); set.add(4); set.add(9); //不能直接对set排序 //Collections.sort(set); List setList = new ArrayList(set); Collections.sort(setList); for (Iterator iter=setList.iterator(); iter.hasNext();) { System.out.println(iter.next()); } System.out.println(“---二分法查找--"); int index = Collections.binarySearch(setList, 9); System.out.println("index=" + index); System.out.println(“---反转集合元素--"); Collections.reverse(setList); for (Iterator iter=setList.iterator(); iter.hasNext();) { System.out.println(iter.next()); } } }
- Java集合--简单讲解
- java常用集合框架简单讲解
- java集合框架讲解
- java集合的讲解
- java集合Collection讲解
- java集合讲解
- java集合讲解
- java集合讲解
- java集合框架的讲解
- java集合框架的讲解
- Java 集合SortedSet&SortedMap讲解
- java集合框架的讲解
- java集合类的讲解
- java集合框架的讲解
- Java简单注释讲解
- java反射简单讲解
- Java流--简单讲解
- Java进程--简单讲解
- HDFS常用命令
- 使用ide开发一个servlet,该servlet显示当前helloworld以及当前日期(MyEclipse)
- span标签里的内容过长设置隐藏(CSS)
- 基于CUDA的遥感影像SLIC分割
- 1002. A+B for Polynomials (25)
- Java集合--简单讲解
- leetcode 646. Maximum Length of Pair Chain
- 配置了 Spring AOP 但会调用两次的问题解决方法
- java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet
- java学习实现日历
- 1003. Emergency (25)
- Nutch2.3.1+HBase单机版
- hdfs第四步报错format namenode
- 2017 Multi-University Training Contest