Java 进阶(4) 集合
List接口
List作为Collection集合的⼦接⼝,不但继承了Collection接⼝中的全部⽅法,⽽且还增加了⼀些根据元素索引来操作集合的特有⽅法,如下:
public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
public E get(int index) :返回集合中指定位置的元素。
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element) :⽤指定元素替换集合中指定位置的元素,返回值的更新前的元素。
List集合特有的⽅法都是跟索引相关
List实现类
ArrayList
特点:有序、有下标、元素可以重复。
List作为Collection集合的⼦接⼝,不但继承了Collection接口中的全部⽅法,⽽且还增加了⼀些根据元素索引来操作集合的特有⽅法,如下:
public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
public E get(int index) :返回集合中指定位置的元素。
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element) :⽤指定元素替换集合中指定位置的元素,返回值的更新前的元素。
List集合特有的⽅法都是跟索引相关
数据结构:数组
特点
查询快:数组是一块联系的空间通过首地址,可以找到数组,通过索引可以找到数组中的某个元素
增删慢:数组的长度是固定的,我们希望增加或者删除一个元素,必须创建一个新数组,把源数组的数据复制过来
在堆内存中,频繁的创建销毁数组,复制数组中的元素,效率低下
示例:
List<String> list = new ArrayList();
list.add("wowo");
list.add("aa");
list.add("dd");
System.out.println(list);
list.add(1,"cc");//在指定的下标添加元素
System.out.println(list);String ele = list.get(1);//获取指定下标的元素;
System.out.println("ele:"+ele);int index = list.indexOf("ada");//返回元素所在的下标;
System.out.println("index:"+index);String remove = list.remove(2);//删除指定下标的元素
System.out.println("remove:"+remove);
System.out.println(list);
boolean flag = list.remove("ads");
System.out.println("flag:"+flag);
System.out.println(list);list.set(1,"XXXX");//设置指定下标的元素
System.out.println(list);
list.add("hello");
list.add("wowo");
System.out.println(list);List sublist = list.subList(2,4);//返回⼀个指定下标范围之间的⼦集
System.out.println(sublist);
Object[] objects = list.toArray();
System.out.println(Arrays.toString(objects));
LinkedList
java.util.LinkedList 集合数据存储的结构是链表结构,⽅便元素添加、删除的集合,访问遍历相对于ArrayList较慢。
数据结构:链表
特点:
查询慢:链表中地址不是连续的,每次查询元素,必须从头开始查询
增删快:链表结构,增加/删除一个元素,对链表的整体结构没有影响,所以增删快
链表中每一个元素也称之为一个节点,一个节点包含了一个数据源
单向链表:链表只有一条链子
双向链表:链表中有两条链子
实际开发中对⼀个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了⼤量首尾操作的方法。这些方法我们作为了解即可:
public void addFirst(E e) :将指定元素插⼊此列表的开头。
public void addLast(E e) :将指定元素添加到此列表的结尾。
public E getFirst() :返回此列表的第⼀个元素。
public E getLast() :返回此列表的最后⼀个元素。
public E removeFirst() :移除并返回此列表的第⼀个元素。
public E removeLast() :移除并返回此列表的最后⼀个元素。
public E pop() :从此列表所表示的堆栈处弹出⼀个元素。
public void push(E e) :将元素推⼊此列表所表示的堆栈。
public boolean isEmpty() :如果列表不包含元素,则返回true。
示例:
public class LinkedListDemo {public static void main(String[] args) {LinkedList<String> link = new LinkedList<String>();//添加元素link.addFirst("abc1");link.addFirst("abc2");link.addFirst("abc3");System.out.println(link);// 获取元素System.out.println(link.getFirst());System.out.println(link.getLast());// 删除元素System.out.println(link.removeFirst());System.out.println(link.removeLast());while (!link.isEmpty()) { //判断集合是否为空System.out.println(link.pop()); //弹出集合中的栈顶元素}System.out.println(link);}
}
Set接口
特点:⽆序、⽆下标、元素不可重复。
⽅法:全部继承⾃Collection中的⽅法。
使⽤foreach循环遍历:
for(数据类型 局部变量 : 集合名){ //循环内部的局部变量,代表当次循环从集合中取出的对象
}
Set实现类
HashSet
特点:⽆序,去重
JDK提供的类:String,Integer可以直接添加到HashSet,⾃动去重;
⾃定义类:⾃⼰重写hashCode()和equals(),必须同时重写。
⾃定义类
public class Person implements Comparable<Person> {private String name;private int age;@Overridepublic int compareTo(Person o) {if(age>o.getAge()){return 1;}else if(age<o.getAge()){return -1;}else{return name.compareTo(o.getName());}//return 0;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age && name.equals(person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}@Overridepublic String toString() {return "Person{" +"name='" + name + '\\'' +", age=" + 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;}
}
示例:
Set<String> set1 = new HashSet<>();
set1.add("aaa");
set1.add("bbb");
set1.add("ccc");
set1.add("ddd");
System.out.println(set1);boolean flag = set1.add("aaa");//添加的时候,判断是否重复
System.out.println("flag:"+flag);
System.out.println(set1);System.out.println("-------------------");
Set<Integer> set2 = new HashSet<>();
set2.add(1);
set2.add(2);
set2.add(3);
set2.add(2);
System.out.println(set2);Person p1 =new Person("张三",23);
Person p2 = new Person("lisi",56);
Person p3 = new Person("张三",23);
Set<Person> set3 = new HashSet<>();
set3.add(p1);
set3.add(p2);
set3.add(p3);
System.out.println(set3);
TreeSet
特点:有序,去重
JDK提供的类String,Integer,已经实现了这个Comparable接⼝;⾃动有序去重;
⾃定义的类:实现Comparable接⼝的compareTo⽅法,在这个⽅法⾥写相应的排序的规则
示例:
Set<String> set1 =new TreeSet<>();
set1.add("aaa");
set1.add("ccc");
set1.add("ddd");
set1.add("bbb");
System.out.println(set1);boolean flag = set1.add("aaa");
System.out.println("flag:"+flag);
System.out.println(set1);Person p1 =new Person("张三",23);
Person p2 = new Person("lisi",56);
Person p3 = new Person("wowo",23);Set<Person> set2 =new TreeSet<>();
set2.add(p1);
set2.add(p2);
set2.add(p3);
System.out.println(set2);
Comparator接口:
⽐较器,实现定制⽐较。
compare(o1,o2)⽅法的返回值0,表示重复。
示例:
public class TestComparator {public static void main(String[] args) {//创建集合,并指定⽐较规则TreeSet<Person> persons=new TreeSet<>(new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {int n1=o1.getAge()-o2.getAge();int n2=o1.getName().compareTo(o2.getName());return n1==0?n2:n1;}});Person p1=new Person("xyz", 20);Person p2=new Person("hello", 22);Person p3=new Person("zhangsan", 25);Person p4=new Person("lisi", 25);persons.add(p1);persons.add(p2);persons.add(p3);persons.add(p4);System.out.println(persons.toString());}
}
Map接⼝
map接口,也是⼀种容器。存储的数据是成对⼉出现。键(key)-->值(value)。
map存储的是键值对:key-value
注意点:
1.存储⽆序的键值对。
2.key必须是唯⼀的。⽽且和value是⼀⼀对应的。
常用方法:
方法名 |
描述 |
V put(K key,V value) |
将对象存⼊到集合中,关联键值。key重复则覆盖原值。 |
Object get(Object key) |
根据键获取对应的值。 |
Set keySet() |
返回所有key。 |
Collection values() |
返回包含所有值的Collection集合。 |
Set> entrySet() |
键值匹配的Set集合。 |
Map实现类
HashMap
JDK1.2版本,线程不安全,运⾏效率快。
允许⽤null 作为key或是value。
存储结构:哈希表。
示例:
/*
put(key,value):往map集合中添加键值对
get(key):根据key,获取value;
remove(key):根据key,删除对应的键值对
keySet:key的集合
*/
Map<String,String> map = new HashMap<>();
String s1 = map.put("A", "aaa");//向Map集合中添加键值对
System.out.println("s1:"+s1);
System.out.println(map);map.put("B","bbb");
map.put("C","ccc");
System.out.println(map);
String s2 = map.put("C", "vvvv");//如果有是重复的key,那么会覆盖原来的value,同时会返回被覆盖的value值
System.out.println("s2:"+s2);
System.out.println(map);System.out.println("---------------");
String value = map.get("C");//获取指定的key 对应的value
System.out.println("value---->"+value);
System.out.println("------------");System.out.println("size:"+map.size());
map.remove("C");
System.out.println(map);
//遍历map的key,然后根据key取相应的值,完成遍历
Set<String> keySet = map.keySet();
for(String key:keySet){System.out.println(key+"------->"+map.get(key));
}
TreeMap
实现了SortedMap接⼝(Map的⼦接⼝),可以对key⾃动排序,Key需实现Comparable接⼝。
示例:
Map<String,String> map = new TreeMap<>();
map.put("B","bbb");
map.put("A", "aaa");
map.put("C","ccc");
System.out.println(map);
Collections⼯具类
常用方法:
方法 |
描述 |
public static void reverse(List list) |
反转集合中元素的顺序 |
public static void shuffle(List list) |
随机重置集合元素的顺序 |
public static void sort(List list) / |
升序排序(元素类型必须实现Comparable接⼝) |
public static int binarySearch( list, T key) |
⼆分查找 |
示例:
List<String> list1 = new ArrayList<>();
//向指定的集合中添加元素
Collections.addAll(list1,"aaa","bbb","ccc","ddd");
System.out.println(list1);
//找到指定的元素的下标
int index = Collections.binarySearch(list1,"bbb");
System.out.println("index:"+index);
Collections.reverse(list1);//反转指定列表中元素的顺序。
System.out.println(list1);
//使⽤默认的随机源随机排列指定的列表。
Collections.shuffle(list1);
System.out.println(list1);
//排序
Collections.sort(list1);
System.out.println(list1);