java的两种类型的容器:
- 合集(collection)
- 映射表(map)
List的两种具体类:
A. ArrayList:用数组存储,数组动态创建。容量会自动变大,但不会自动减小
B.LinkedList:链表存储<br>
注:
1.如果通过下标来随机访问元素,且不会在线性表的起始位置插入或删除元素,使用ArrayList效率更高
2.Array(数组)和ArrayList的区别:
a.Array是数组,一旦创建大小是固定的,ArrayList的大小是动态可变的
b.ArrayList实现了更多的方法和特性
c.Array可以存储基本类型和对象类型,ArrayList只能存储对象类型
Comparable和Comparator
相同点:<br>
1.两者都用作对象之间的比较,都可以自定义比较规则;
2.两者都是返回一个描述对象关系的int类型整数;
不同点:
1.实现了Comparable标识可以用自己与另一个对象进行比较;而实现了Comparator表示我可以比较其他的两个对象;
2.使用Comparable需要修改原来的实体类,属于自然排序。而Comparator不用修改
3.修改了Comparable实体类,Comparable也仅有一种比较规则。而Comparator可以实现多个比较规则
Comparable:内比较器,是一个接口。实现该接口需要实现接口中的comparaTo(Object o)方法,主要是当前对象与对象o比较
Comparator:外比较器,是一个接口。实现该接口需要实现接口中的compare方法。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
class Person {
public String name;
public int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name+" "+age;
}
}
public class TestComparator {
public static void main(String[] args) {
Collection<Person> collection=new ArrayList<>();
collection.add(new Person("zhang",21));
collection.add(new Person("liu",23));
collection.add(new Person("song",22));
collection.add(new Person("bong",22));
collection.add(new Person("rong",22));
collection.add(new Person("uong",22));
((ArrayList<Person>) collection).sort(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if(o1.age<o2.age)
return -1;
else if (o1.age>o2.age)
return 1;
else{
if(o1.name.compareTo(o2.name)<0){
return -1;
}
else if (o1.name.compareTo(o2.name)>0)
return 1;
else{
return 0;
}
}
}
});
for (Person p:collection) {
System.out.println(p.toString());
}
}
}
向量类和栈类
Stack类:pop();push(a);peek();
class Student{
String name;
public Student(String n){
name=n;
}
@Override
public String toString() {
return name;
}
}
public class TestStack {
public static void main(String[] args) {
Stack< Student > students=new Stack<>();
students.push(new Student("S"));
students.push(new Student("C"));
students.push(new Student("B"));
students.push(new Student("h"));
students.push(new Student("y"));
students.push(new Student("j"));
System.out.println("after push:");
for (Student s:students
) {
System.out.println(s.toString());
}
Student student=students.pop();
System.out.println("pop->"+student.name);
System.out.println("after pop:");
for (Student s:students
) {
System.out.println(s.toString());
}
Student ss=students.peek();
System.out.println("after peek:");
for(Student st:students
) {
System.out.println(st.toString());
}
}
}
队列和优先队列
Queue接口:不能世界实例化Queue接口,可使用LinkedList替代。LinkedList实现了Dueue接口,Dueue接口实现了queue接口。 PriortyQueue类:优先队列。默认用Comparable以元素的自然顺序进行排序。拥有最小值的元素具有最高优先级,使用时最先从队列中删除,e若元素值相同则随机删除。
import java.util.PriorityQueue;
class Person implements Comparable<Person>{
public String name;
public int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name+" "+age;
}
@Override
public int compareTo(Person o) {//自定义排序规则
if (age< o.age)
return -1;
else if (age==o.age)
return 0;
else{
if(name.compareTo(o.name)<0)
return -1;
else if (name.compareTo(o.name)==0)
return 0;
else{
return 1;
}
}
}
}
public class PriorityQueueDemo {
public static void main(String[] args) {
PriorityQueue<Person> priorityQueue=new PriorityQueue<>();
priorityQueue.offer(new Person("A",12));//offer操作将特定元素插入优先级队列,顺序方式参照元素实现的Comparable的compareTo方法。
priorityQueue.offer(new Person("B",11));
priorityQueue.offer(new Person("C",15));
System.out.println("output after some offer operations:");
for (Person p:priorityQueue
) {
System.out.println(p.toString());
}
}
}
输出:
output after some offer operations:
B 11
A 12
C 15
Set/Map
set接口拓展了Collection接口,规定其中不能包含重复元素:在集合中,不存在有元素e1,e2满足e1.equals(e2)返回值为true;
set的三个具体类:1.散列类HashSet
2.链式散列集LinkedHashSet
3.树形集TreeSet
hashSet
a.默认,初始容量为16,负载系数为0.75(0-1.0)
b.在增加集合的容量时,当元素个数超过了容量和负载系数的乘积,容量自动翻倍
c.HashSet可以用来存储互不相同的任何元素,若重复添加相同元素,则只添加第一次
d.hashCode方法:
1.若两个对象相等则散列值必须相等
2.两个不相等的对象可能有相同的哈希值
package hashSetDemo;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<String> set =new HashSet<>();
set.add("beijing");
set.add("shanghai");
set.add("london");
set.add("shanghai");//重复加入shanghai
set.add("newyork");
set.add("paris");
System.out.println(set);
for (String s :
set) {
System.out.print(s.toUpperCase()+" ");
}
}
}
output(自动去除了重复元素):
[london, newyork, paris, shanghai, beijing]
LONDON NEWYORK PARIS SHANGHAI BEIJING
LinkedHashSet
1.用链表实现来扩展HashSet
2.和HashSet的主要区别:HashSet中的元素没有排序,而LinkedHashSet可以按照插入的顺序排序
3.也不允许出现重复元素
eg.
package linkedHashSetDemo;
import java.sql.SQLOutput;
import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHshSetMap {
public static void main(String[] args) {
Set<String> set=new LinkedHashSet<>();
set.add("A");
set.add("A");
set.add("B");
set.add("C");
set.add("D");
set.add("E");
set.add("F");
set.add("G");
set.add("H");
set.add("I");
System.out.println(set);
}
}
输出:
[A, B, C, D, E, F, G, H, I]
TreeSet
1.Set的一个子接口,确保集合中的元素是有序的
2.方法:
last()
first()
headSet(Element toElement):集合中小于toElement的元素集合(返回值为SortedSet类型)
tailSet(Element fromElement):返回集合中大于等于fromElement的元素集合(返回值为SortedSet类型)
注:TreeSet是SortedSet的实现类
3.如果使用无参构造方法创建了一个TreeSet对象,则会假定元素类实现了Comparable接口,要使用Comparator接口,则必须使用构造方法:new TreeSet(Comparator com)
*自定义排序方式的两种方式
eg1.
class Person implements Comparable{//元素类实现了Comparable接口
@override
public int compareTo(Person o){
...
return ;
}
}
public class Demo{
public static void main(String[] args) {
TreeSet<Person> treeSet=new TreeSet<>();
...
}
}
eg2.
public class Demo{
public static void main(String[] args) {
TreeSet<Person> treeSet2=new TreeSet<>(new Comparator<String>(){
@Override
public int compare(String o1, String o2) {
return 0;
}
});
...
}
}
package hashSetDemo;
import java.util.HashSet;
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) {
HashSet<String> hashSet=new HashSet<>();
hashSet.add("A");
hashSet.add("A");
hashSet.add("E");
hashSet.add("F");
// hashSet.add("B");
hashSet.add("C");
hashSet.add("D");
System.out.println("HashSet:"+hashSet);
TreeSet<String> treeSet=new TreeSet<>(hashSet);
System.out.println("TreeSet:"+treeSet);
System.out.println("TreeSet->first():"+treeSet.first());
System.out.println("TreeSet->last():"+treeSet.last());
System.out.println("TreeSet->headSet()"+treeSet.headSet("G"));
System.out.println("TreeSet->tailSet()"+treeSet.tailSet("B"));
TreeSet<String> treeSet1=new TreeSet<>();
treeSet1.add("A");
treeSet1.add("A");
treeSet1.add("B");
treeSet1.add("C");
treeSet1.add("D");
treeSet1.add("E");
treeSet1.add("F");
//返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。
System.out.println("TreeSet->ceiling()"+treeSet1.ceiling("B"));
}
}
output:
HashSet:[A, C, D, E, F]
TreeSet:[A, C, D, E, F]
TreeSet->first():A
TreeSet->last():F
TreeSet->headSet():[A, C, D, E, F]
TreeSet->tailSet():[C, D, E, F]
TreeSet->ceiling():B
映射表map
1.一种依照键/值对存储元素的容器
2.键可以是任意类型的对象
3.一个键和他对应的值作为一个条目被保存在映射表中
4.分为三类:HashMap、LinkedHashMap、TreeMap
5.如果需要更新映射表时不需要改变映射表中的顺序,就是用HashMap;如果需要按元素的插入顺序或访问顺序,则使用LinkedHashMap;如果需要使用映射表按照键排序,就是用TreeMap
LinkedHashMap
1.使用链表拓展实现了HashMap类
2.支持插入排序(插入map的顺序)和访问顺序排序(按最后一次被访问的顺序)
TreeMap
1.在遍历排好顺序的键时很高效
2.键可以使用Comparator接口或Comparable接口进行自定义排序
package hashSetDemo;
import java.util.*;
public class Demo{
public static void main(String[] args) {
HashMap<String,Integer> hashMap=new HashMap<>();
hashMap.put("A",10);
hashMap.put("B",11);
hashMap.put("C",23);
hashMap.put("E",11);
hashMap.put("G",23);
hashMap.put("P",11);
hashMap.put("R",23);
System.out.println("hashMap:"+hashMap);
TreeMap treeMap=new TreeMap<>(hashMap);
System.out.println("TreeMap:"+treeMap);
}
}
output:
hashMap:{P=11, A=10, B=11, R=23, C=23, E=11, G=23}
TreeMap:{A=10, B=11, C=23, E=11, G=23, P=11, R=23}
Map应用实例1:统计文本中单词出现的频率
import java.util.*;
public class Demo{
public static void main(String[] args) {
String text = "Good Moring . have a good class. Hava a good visit. have fun!";
Map<String,Integer> map=new HashMap<>();
//将语句分隔开存储在words数组
String[] words=text.split("[ \n\t\r.,;:!?(){}]");
for (int i=0;i<words.length;i++){
String key=words[i].toLowerCase();
if(key.length()>0){
//map不包含该key,加入
if (!map.containsKey(key)){
map.put(key,1);
}
else{
//map.get(key):获取key键值对应的value
int value=map.get(key);
value++;
//map.put:若该元组不存在,则加入;若存在,则更新,即如果此映射以前包含一个该键的映射关系,则用指定值替换旧值(当且仅当 m.containsKey(k) 返回 true 时,才能说映射 m 包含键 k 的映射关系)
map.put(key,value);
}
}
}
//如果想单独访问Map的元素,需将其转化为实体集Set,用到map.entrySet().
Set<Map.Entry<String,Integer>> entrySet=map.entrySet();
for (Map.Entry<String, Integer> entry:
entrySet) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
}
}
output:
a 2
moring 1
hava 1
have 2
visit 1
good 3
class 1
fun 1
map应用实例2:查找字符串数组重复次数最多的字符串的重复次数
import java.util.*;
public class Demo{
public static void main(String[] args) {
String []text = {"Hello","Back","Demo","Demo","Demo","Good","Good","some","Double","long","Hello","Hello","Hello"};
Map<String,Integer> map=new HashMap<>();
for (String s :
text) {
Integer integer=map.get(s);
map.put(s,integer==null?1:integer+1);
}
int max=-1;
String res="";
for (Map.Entry<String,Integer> entry:
map.entrySet()){
System.out.println(entry.getKey()+" "+entry.getValue());
if(max<entry.getValue()){
max=entry.getValue();
res=entry.getKey();
}
}
System.out.println("重复次数最多的字符串为 \""+res+"\" ,重复次数为"+max);
}
}
output:
some 1
Demo 3
Hello 4
Back 1
Good 2
Double 1
long 1
重复次数最多的字符串为 "Hello" ,重复次数为4