java中List与Set的常用用法
来源:互联网 发布:ibm人工智能 编辑:程序博客网 时间:2024/06/13 04:19
java中的集合主要分为三种:Set(集)、List(列表)、Map(映射)
下图为List、Set和Collection的联系,我们可以看出List和Set均继承自Collection,值得注意的是List、Set和Collection都为接口,不能直接实例化对象。List的两个实现类为ArrayList和LinkedList。
1.List集合的元素是有序的(取出顺序和存储顺序一致),元素可以重复
(1)ArrayList:继承了List的特点,底层数据结构是数组,因此它的查询速度快,但是增删速度慢。他是线程不安全的,效率高。
(2)LinkedList:同样继承了List的特点,底层数据结构是链表,所以它的增删速度快,查询速度慢。线程不安全、效率高。
新建一个测试学生类,这里只说引用类型,不讨论基本类型,后面不再论述。
<span style="font-size:18px;">public class Student {private String name;//学生姓名private int age;//学生姓名//构造函数public Student(String name, int age) {super();this.name = name;this.age = age;}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;}@Override//重写toString()方法public String toString() {return "姓名:" + name + "\t 年龄:" + age;}}</span>鉴于篇幅原因,这里只给出ArrayList的代码,因为LinkedList和ArrayList一样的。
<span style="font-size:18px;">public static void main(String[] args) {//创建一个ArrayList的集合ArrayList<Student> list = new ArrayList<Student>();Student s1 = new Student("张三", 19);//创建学生对象Student s2 = new Student("李四", 17);Student s3 = new Student("小明", 18);Student s4 = new Student("小红", 22);Student s5 = new Student("李四", 17);list.add(s1); //增加成员list.add(s2); list.add(s3); list.add(s4); list.add(s5); //有三种遍历方式//1.迭代器//Iterator<Student> iterator = list.iterator();//while (iterator.hasNext()) {//System.out.println(iterator.next());//}//2.for循环遍历//for (int i = 0; i < list.size(); i++) {//System.out.println(list.get(i));//}//3.增强for循环for (Student student : list) {System.out.println(student);}}</span>
通过重写Collectios的sort方法可以实现自定排序,以上面为例,按年龄从小到大排序:
<span style="font-size:18px;">//重写sort方法,通过匿名内部类实现Collections.sort(list,new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {if((o1.getAge()-o2.getAge())>0){return 1;}else if((o1.getAge()-o2.getAge())<0){return -1;}elsereturn 0;}});</span>
还可以通过在自定义类(Student类)中实现Comparable接口,重写compareTo()方法来实现自定义排序,按年龄从大到小排序:
<span style="font-size:18px;">@Overridepublic int compareTo(Student o) {if((this.getAge()-o.getAge())>0){return 1;}else if((this.getAge()-o.getAge())<0){return -1;}elsereturn 0;}</span>
1.Set集合的元素是唯一的,不可重复(有两种遍历方式:1.迭代器,2.增强for.代码参照上面)
(1)HashSet:继承了Set的特点,元素唯一,但是无序。底层数据结构是哈希表,通过重写HashCode()方法和equals()方法可以保证元素的唯一性。
(2)TreeSet:继承了Set的特点,元素唯一而且有序(使用元素的自然顺序对元素进行排序,或者根据创建 set时提供的 Comparator进行排序,具体取决于使用的构造方法)。底层数据结构是二叉树,通过Compareable接口的compareTo()方法来保证元素的唯一性。
<span style="font-size:18px;">public static void main(String[] args) {//创建一个HashSet的集合HashSet<Student> hs = new HashSet<Student>();Student s1 = new Student("张三", 19);//创建学生对象Student s2 = new Student("李四", 17);Student s3 = new Student("小明", 18);Student s4 = new Student("小红", 22);Student s5 = new Student("李四", 17);hs.add(s1); //增加成员hs.add(s2); hs.add(s3); hs.add(s4); hs.add(s5); for (Student student : hs) {System.out.println(student);}</span>
运行上面的程序我们发现,咦,怎么有两个 "李四",17 ,这是因为没有重写HashCode()方法和equals()方法,导致元素不是唯一的,解决方案就是在Student类中重写HashCode()方法和equals()方法即可。
自动重写HashCode()方法和equals()方法步骤:右击选择Source,找到Generate hashCode() and equals(),点击去,全选确定即可,系统会自动帮你重写。代码入下:
<span style="font-size:18px;">@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic 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;return true;}</span>运行后发现李四只剩一个了,这是因为重写了HashCode()方法和equals()方法,保证了元素的唯一性。
下面是TreeSet的:
<span style="font-size:18px;">public static void main(String[] args) {//创建一个TreeSet的集合TreeSet<Student> hs = new TreeSet<Student>();Student s1 = new Student("张三", 19);//创建学生对象Student s2 = new Student("李四", 17);Student s3 = new Student("小明", 18);Student s4 = new Student("小红", 22);Student s5 = new Student("李四", 17);hs.add(s1); //增加成员hs.add(s2); hs.add(s3); hs.add(s4); hs.add(s5); for (Student student : hs) {System.out.println(student);}}</span>
运行上面的代码会发现error:Exception in thread "main" java.lang.ClassCastException.这又是怎么回事?这是因为
TreeSet通过Compareable接口的compareTo()方法来保证元素的唯一性。可以通过下面两种方式来解决:
1.自定义类(Student)继承Comparable接口重写compareTo()方法来实现
以上面Student类为例,按年龄从小到大排序
<span style="font-size:18px;">@Overridepublic int compareTo(Student o) {if((this.getAge()-o.getAge())>0){return 1;}else if((this.getAge()-o.getAge())<0){return -1;}elsereturn 0;}</span>
对于这种方式,TreeSet采用的构造器应当是无参的,也就是使用元素的自然顺序对元素进行排序。
2.创建set集合的时候,传入Comparator进行排序,进行排序,也叫作比较器排序
public static void main(String[] args) {//创建一个TreeSet的集合TreeSet<Student> hs = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {int num1 = o1.getAge() - o2.getAge();int num2 = num1==0?o1.getName().compareTo(o2.getName()):num1;return num2;}});Student s1 = new Student("张三", 19);//创建学生对象Student s2 = new Student("李四", 17);Student s3 = new Student("小明", 18);Student s4 = new Student("小红", 22);Student s5 = new Student("李四", 17);hs.add(s1); //增加成员hs.add(s2); hs.add(s3); hs.add(s4); hs.add(s5); for (Student student : hs) {System.out.println(student);}}这里使用了内部类,也达到了同样的目的。
- java中List与Set的常用用法
- Java中Set、Map、List的用法与区别
- java中 List 与Set 的区别
- java中 List 与Set 的区别
- java中 List 与Set 的区别
- java中 List 与Set 的区别
- Java中的Set、List、Map的用法与区别
- Java中的Set、List、Map的用法与区别
- java中的Set、List、Map的区别与用法
- JAVA Map、Set、List、Queue、Stack的特点与用法
- Java中 Map、Set、List的基本用法
- java 中list,set,map集合的用法和区别
- java 中list,set,map集合的用法和区别
- java中list,set,map用法的区别
- java中String、List、set的一些常用方法
- java中Map,List与Set的区别与联系
- List与Set的用法(转载)
- JAVA中List、Map、Set的区别与选用
- C++注意防止指针指向空
- HTTP403错误
- VS2013发布C#自动更新程序
- 《JAVA并发编程实践》读书笔记(四)
- MySQL 的时间查询语句
- java中List与Set的常用用法
- Android 相关属性
- JAVA——继承
- 在SVM实现多分类的程序基础工作
- Eclipse中如何用键盘单击或选中对话框中的元素?
- Light OJ 1094 Farthest Nodes in a Tree(树的直径模板)
- 判断是否是有效的url
- Shell中让程序造死循环的几种方式
- nginx的通配符哈希表--ngx_hash_wildcard_t