Java集合类二集合类详解及使用
来源:互联网 发布:美国历年财政支出数据 编辑:程序博客网 时间:2024/05/16 19:53
一、常见集合详解与使用
1、ArrayList
ArrayList:实现原理:
数组实现,查找快,增删慢
数组为什么是查询快?因为数组的内存空间地址是连续的.
ArrayList底层维护了一个Object[]用于存储对象,默认数组的长度是10。可以通过 new ArrayList(20)显式的指定用于存储对象的数组的长度。
当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来的容量的1.5倍。
由于ArrayList是数组实现,在增和删的时候会牵扯到数组增容,以及拷贝元素.所以慢。数组是可以直接按索引查找,所以查找时较快
可以考虑,假设向数组的0角标未知添加元素,那么原来的角标位置的元素需要整体往后移,并且数组可能还要增容,一旦增容,就需要要将老数组的内容拷贝到新数组中.
所以数组的增删的效率是很低的.
ArrayList使用:
去除ArrayList中重复元素:
public class Demo6 { public static void main(String[] args) { ArrayList arr = new ArrayList(); Person p1 = new Person("jack", 20); Person p2 = new Person("rose", 18); Person p3 = new Person("rose", 18); arr.add(p1); arr.add(p2); arr.add(p3); System.out.println(arr); ArrayList arr2 = new ArrayList(); for (int i = 0; i < arr.size(); i++) { Object obj = arr.get(i); Person p = (Person) obj; if (!(arr2.contains(p))) { arr2.add(p); } } System.out.println(arr2); }}class Person { private String name; private int age; public Person() { } public Person(String name, int age) { 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 public int hashCode() { return this.name.hashCode() + age * 37; } @Override public boolean equals(Object obj) { if (!(obj instanceof Person)) { return false; } Person p = (Person) obj; return this.name.equals(p.name) && this.age == p.age; } @Override public String toString() { return "Person@name:" + this.name + " age:" + this.age; }}
2、LinkedList
LinkedList:链表实现, 增删快, 查找慢
由于LinkedList:在内存中的地址不连续,需要让上一个元素记住下一个元素.所以每个元素中保存的有下一个元素的位置.虽然也有角标,但是查找的时候,需要从头往下找,显然是没有数组查找快的.但是,链表在插入新元素的时候,只需要让前一个元素记住新元素,让新元素记住下一个元素就可以了.所以插入很快.
由于链表实现, 增加时只要让前一个元素记住自己就可以, 删除时让前一个元素记住后一个元素, 后一个元素记住前一个元素. 这样的增删效率较高。
但查询时需要一个一个的遍历,所以效率较低。
LinkedList使用:
基本方法:
import java.util.Iterator;import java.util.LinkedList;public class Demo3 { public static void main(String[] args) { LinkedList list = new LinkedList(); list.add("西游记"); list.add("三国演义"); list.add("石头记"); list.add("水浒传"); list.add("全球通史"); list.addFirst("史记"); list.addLast("呐喊"); // list.addFirst(null); // list.addLast(null); System.out.println(list); // 获取指定位置处的元素。 String str = (String) list.get(0); // 返回此列表的第一个元素。 String str2 = (String) list.getFirst(); System.out.println(str.equals(str2)); // 获取指定位置处的元素。 String str3 = (String) list.get(list.size() - 1); // 返回此列表的最后一个元素。 String str4 = (String) list.getLast(); System.out.println(str3.equals(str4)); // 获取但不移除此列表的头(第一个元素)。 Object element = list.element(); System.out.println(element); int size = list.size(); System.out.println(size);}LinkedList的迭代:
mport java.util.Iterator;import java.util.LinkedList;public class Demo3 {public static void main(String[] args) {LinkedList list = new LinkedList();list.add("西游记");list.add("三国演义");list.add("石头记");list.add("水浒传");list.add("全球通史");Iterator it = list.iterator();while (it.hasNext()) {String next = (String) it.next();System.out.println(next);}}}
ArrayList和 LinkedList的存储查找的优缺点:
(1)ArrayList 是采用动态数组来存储元素的,它允许直接用下标号来直接查找对应的元素。但是,但是插入元素要涉及数组元素移动及内存的操作。总结:查找速度快,插入操作慢。
(2)LinkedList 是采用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快
3、VectorVector: 描述的是一个线程安全的ArrayList。
使用:
public static void main(String[] args) {Vector v = new Vector();v.addElement("aaa");v.addElement("bbb");v.addElement("ccc");System.out.println( v );System.out.println( v.elementAt(2) ); // ccc// 遍历Vector遍历Enumeration ens = v.elements();while ( ens.hasMoreElements() ){System.out.println( ens.nextElement() );}}
Set
Set所包含集合用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。
4、HashSet
哈希表边存放的是哈希值。HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同)是按照哈希值来存的所以取数据也是按照哈希值取得。
HashSet会通过元素的hashcode()和equals方法进行判断元素师否重复。
向hashSet中添加自定义对象,并判断是否是重复对象的代码如下:
import java.util.HashSet;import java.util.Iterator;public class Demo4 {public static void main(String[] args) {HashSet hs = new HashSet();hs.add(new Person("jack", 20));hs.add(new Person("rose", 20));hs.add(new Person("hmm", 20));hs.add(new Person("lilei", 20));hs.add(new Person("jack", 20));Iterator it = hs.iterator();while (it.hasNext()) {Object next = it.next();System.out.println(next);}}}class Person {private String name;private int age;Person() {}public Person(String name, int age) {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;}@Overridepublic int hashCode() {System.out.println("hashCode:" + this.name);return this.name.hashCode() + age * 37;}@Overridepublic boolean equals(Object obj) {System.out.println(this + "---equals---" + obj);if (obj instanceof Person) {Person p = (Person) obj;return this.name.equals(p.name) && this.age == p.age;} else {return false;}}@Overridepublic String toString() {return "Person@name:" + this.name + " age:" + this.age;}}
5、TreeSet
TreeSet会对元素进行自然排序,所以插入的元素要具备比较性或给其指定比较规则。
给TreeSet指定排序规则的方法:
方式一:元素自身具备比较性
元素自身具备比较性,需要元素实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做元素的自然排序也叫做默认排序。
示例代码:
public class Demo4 {public static void main(String[] args) {TreeSet ts = new TreeSet();ts.add(new Person("aa", 20, "男"));ts.add(new Person("bb", 18, "女"));ts.add(new Person("cc", 17, "男"));ts.add(new Person("dd", 17, "女"));ts.add(new Person("dd", 15, "女"));ts.add(new Person("dd", 15, "女"));System.out.println(ts);System.out.println(ts.size()); // 5}}class Person implements Comparable {private String name;private int age;private String gender;public Person() {}public Person(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}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;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}@Overridepublic int hashCode() {return name.hashCode() + age * 37;}public boolean equals(Object obj) {System.err.println(this + "equals :" + obj);if (!(obj instanceof Person)) {return false;}Person p = (Person) obj;return this.name.equals(p.name) && this.age == p.age;}public String toString() {return "Person [name=" + name + ", age=" + age + ", gender=" + gender+ "]";}@Overridepublic int compareTo(Object obj) {Person p = (Person) obj;System.out.println(this+" compareTo:"+p);if (this.age > p.age) {return 1;}if (this.age < p.age) {return -1;}return this.name.compareTo(p.name);}}
方式二:容器具备比较性
当元素自身不具备比较性,或者自身具备的比较性不是所需要的。那么此时可以让容器自身具备。需要定义一个类实现接口Comparator,重写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。
示例代码:
public class Demo5 {public static void main(String[] args) {TreeSet ts = new TreeSet(new MyComparator());ts.add(new Book("think in java", 100));ts.add(new Book("java 核心技术", 75));ts.add(new Book("现代操作系统", 50));ts.add(new Book("java就业教程", 35));ts.add(new Book("think in java", 100));ts.add(new Book("ccc in java", 100));System.out.println(ts); }}class MyComparator implements Comparator {public int compare(Object o1, Object o2) {Book b1 = (Book) o1;Book b2 = (Book) o2;System.out.println(b1+" comparator "+b2);if (b1.getPrice() > b2.getPrice()) {return 1;}if (b1.getPrice() < b2.getPrice()) {return -1;}return b1.getName().compareTo(b2.getName());}}class Book {private String name;private double price;public Book() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public Book(String name, double price) {this.name = name;this.price = price;}@Overridepublic String toString() {return "Book [name=" + name + ", price=" + price + "]";}}
6、LinkedHashSet
会保存插入的顺序
Map
Map中的元素是两个对象,一个对象作为键,一个对象作为值。键不可以重复,但是值可以重复。
7、HashMap底层是哈希表数据结构,线程是不同步的,可以存入null键,null值。要保证键的唯一性,需要覆盖hashCode方法,和equals方法。
示例代码:
import java.util.HashMap;import java.util.Iterator;import java.util.Map.Entry;import java.util.Set;public class Demo3 {public static void main(String[] args) {HashMap<Person, String> hm = new HashMap<Person, String>();hm.put(new Person("jack", 20), "1001");hm.put(new Person("rose", 18), "1002");hm.put(new Person("lucy", 19), "1003");hm.put(new Person("hmm", 17), "1004");hm.put(new Person("ll", 25), "1005");System.out.println(hm);System.out.println(hm.put(new Person("rose", 18), "1006"));Set<Entry<Person, String>> entrySet = hm.entrySet();Iterator<Entry<Person, String>> it = entrySet.iterator();while (it.hasNext()) {Entry<Person, String> next = it.next();Person key = next.getKey();String value = next.getValue();System.out.println(key + " = " + value);}}}class Person {private String name;private int age;Person() {}public Person(String name, int age) {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;}@Overridepublic int hashCode() {return this.name.hashCode() + age * 37;}@Overridepublic boolean equals(Object obj) {if (obj instanceof Person) {Person p = (Person) obj;return this.name.equals(p.name) && this.age == p.age;} else {return false;}}@Overridepublic String toString() {return "Person@name:" + this.name + " age:" + this.age;}}}
8、TreeMap
TreeMap可以对集合中的键进行排序。如何实现键的排序?
方式一:元素自身具备比较性
和TreeSet一样原理,需要让存储在键位置的对象实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做元素的自然排序也叫做默认排序。
方式二:容器具备比较性
当元素自身不具备比较性,或者自身具备的比较性不是所需要的。那么此时可以让容器自身具备。需要定义一个类实现接口Comparator,重写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。
自定义元素排序代码:import java.util.Comparator;import java.util.Iterator;import java.util.Map.Entry;import java.util.Set;import java.util.TreeMap;public class Demo3 {public static void main(String[] args) {TreeMap<Person, String> hm = new TreeMap<Person, String>(new MyComparator());hm.put(new Person("jack", 20), "1001");hm.put(new Person("rose", 18), "1002");hm.put(new Person("lucy", 19), "1003");hm.put(new Person("hmm", 17), "1004");hm.put(new Person("ll", 25), "1005");System.out.println(hm);System.out.println(hm.put(new Person("rose", 18), "1006"));Set<Entry<Person, String>> entrySet = hm.entrySet();Iterator<Entry<Person, String>> it = entrySet.iterator();while (it.hasNext()) {Entry<Person, String> next = it.next();Person key = next.getKey();String value = next.getValue();System.out.println(key + " = " + value);}}}class MyComparator implements Comparator<Person> {@Overridepublic int compare(Person p1, Person p2) {if (p1.getAge() > p2.getAge()) {return -1;} else if (p1.getAge() < p2.getAge()) {return 1;}return p1.getName().compareTo(p2.getName());}}class Person implements Comparable<Person> {private String name;private int age;Person() {}public Person(String name, int age) {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;}@Overridepublic int hashCode() {return this.name.hashCode() + age * 37;}@Overridepublic boolean equals(Object obj) {if (obj instanceof Person) {Person p = (Person) obj;return this.name.equals(p.name) && this.age == p.age;} else {return false;}}@Overridepublic String toString() {return "Person@name:" + this.name + " age:" + this.age;}@Overridepublic int compareTo(Person p) {if (this.age > p.age) {return 1;} else if (this.age < p.age) {return -1;}return this.name.compareTo(p.name);}}
二、迭代器
为了方便的处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素.例如删除和获取集合中的元素.该对象就叫做迭代器(Iterator).
1.Iterator
Iterator接口定义的方法
Itreator 该接口是集合的迭代器接口类,定义了常见的迭代方法
1:boolean hasNext()
判断集合中是否有元素,如果有元素可以迭代,就返回true。
2: E next()
返回迭代的下一个元素,注意: 如果没有下一个元素时,调用next元素会抛出NoSuchElementException
3: void remove()
从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。
使用迭代器遍历
for循环遍历:
import java.util.ArrayList;import java.util.Iterator;public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定对象存储到容器中list.add("计算机网络");list.add("现代操作系统");list.add("java编程思想");list.add("java核心技术");list.add("java语言程序设计");System.out.println(list);for (Iterator it = list.iterator(); it.hasNext();) { //迭代器的next方法返回值类型是Object,所以要记得类型转换。String next = (String) it.next();System.out.println(next);}}}while循环遍历:
public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定对象存储到容器中list.add("计算机网络");list.add("现代操作系统");list.add("java编程思想");list.add("java核心技术");list.add("java语言程序设计");System.out.println(list);Iterator it = list.iterator();while (it.hasNext()) {String next = (String) it.next();System.out.println(next);}}2. List特有的迭代器ListIterator
方法:
---|Iterator
hasNext()
next()
remove()
------| ListIterator Iterator子接口 List专属的迭代器
add(E e) 将指定的元素插入列表(可选操作)。该元素直接插入到next返回的下一个元素的前面(如果有)
void set(E o) 用指定元素替换 next 或 previous 返回的最后一个元素
hasPrevious() 逆向遍历列表,列表迭代器有多个元素,则返回true。
previous() 返回列表中的前一个元素。倒序遍历:
import java.util.ArrayList;import java.util.ListIterator;public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定对象存储到容器中list.add("计算机网络");list.add("现代操作系统");list.add("java编程思想");list.add("java核心技术");list.add("java语言程序设计");System.out.println(list); // 获取List专属的迭代器ListIterator lit = list.listIterator();while (lit.hasNext()) {String next = (String) lit.next();System.out.println(next);}System.out.println("***************");while (lit.hasPrevious()) {String next = (String) lit.previous();System.out.println(next);}}}
- Java集合类二集合类详解及使用
- java集合类详解二
- Java集合:集合类详解
- Java集合排序及java集合类详解
- Java集合排序及java集合类详解
- Java集合排序及java集合类详解:Set
- Java集合排序及java集合类详解
- Java 集合排序及 java 集合类详解
- Java集合排序及java集合类详解
- Java集合排序及java集合类详解
- Java集合排序及java集合类详解:Set
- java集合类详解(二)
- JAVA基础--集合类详解及问题
- JAVA基础--集合类详解及问题
- Java集合类 二
- JAVA 集合类 二
- Java集合排序及java集合类详解:集合框架中常用类比较
- Java集合类详解
- 工作笔记-新系统安装deb文件失败
- SpringMvc实现文件的上传
- C++ helloworld
- kubeadm安装kubernetes(calico)
- 访问网页的各种http状态码的解释说明
- Java集合类二集合类详解及使用
- 数据挖掘学习笔记-关于数据的基本概念
- Linux文件系统调用----实现对树形文件结构的广度优先遍历,即按层输出文件信息
- 使用jsch-spring-boot在本地访问远程云服务
- Faster-Rcnn的loss曲线可视化
- RxJava 1.0版本入门篇之--2
- 玲珑学院 1125 咸鱼商店(二分+01背包)
- Codeforces 817D Imbalanced Array
- 使用git和github进行协同开发流程