集合
Java中的集合是用来存放对象的容器 集合可以存放不同类型,不限数量的数据 分为两块:Collection和Map,也称之为集合接口 集合类都存放在java.util包中
Collection
List
List
被AbstractList实现,然后分为3个子类,ArrayList,LinkedList和VectorListList<E>
是一种有序链表,本身是一个泛型接口,元素可以重复,可以是 null包含以下方法: 遍历List<E>
List< String> list = . . . ;
for ( int i= 0 ; i< list. size ( ) ; i++ ) {
String s = list. get ( i) ;
}
List< String> list = . . . ;
for ( Iterator< String> it = list. iterator ( ) ; it. hasNext ( ) ; ) {
String s = list. next ( ) ;
}
List< String> list = . . . ;
for ( String s : list) {
System. out. println ( s) ;
}
toArray()
方法Arrays.asList()
方法
List< Integer> list = new ArrayList < > ( ) ;
list. add ( 1 ) ;
list. add ( 2 ) ;
list. add ( 3 ) ;
Integer[ ] arr = list. toArray ( new Integer [ list. size ( ) ] ) ;
Integer arr = { 1 , 2 , 3 } ;
List< Integer> arraylist = new ArrayList < > ( Arrays. asList ( arr) ) ;
List< String> list = new ArrayList < > ( ) ;
list. add ( "A" ) ; list. add ( "b" ) ; list. add ( "c" ) ;
list. contains ( "c" ) ;
list. indexOf ( "c" ) ;
list. add ( new String ( "C" ) ) ;
list. contains ( new String ( "C" ) ) ;
ArrayList<E>
:
动态添加元素的方式如下 LinkList<E>
:
内部每个元素都有一个指针,指向下一个元素 添加元素时,只需新建结点,将末尾元素的指针指向即可 通常情况下我们优先考虑使用ArrayList 队列和栈这一块都与LinkedList有关,就在这里介绍了: Queue
:
Queue<E>实现一个先进先出的队列 LinkedList实现了Queue接口,所以可以将LinkedList作为Queue使用 为什么获取都有两种方法? public static void main ( String[ ] args) {
Queue< Person> queue = new LinkedList < > ( ) ;
queue. offer ( new Person ( "Ming" , 12 ) ) ;
queue. offer ( new Person ( "Hong" , 15 ) ) ;
queue. offer ( new Person ( "Jun" , 17 ) ) ;
System. out. println ( queue. poll ( ) ) ;
System. out. println ( queue. poll ( ) ) ;
System. out. println ( queue. poll ( ) ) ;
if ( ! isEmpty ( queue) ) {
System. out. println ( queue. remove ( ) ) ;
}
}
PriorityQueuepublic static void main ( String[ ] args) {
Queue< Person> queue = new PriorityQueue < > ( ) ;
queue. offer ( new Person ( "Ming" , 12 ) ) ;
queue. offer ( new Person ( "Hong" , 15 ) ) ;
queue. offer ( new Person ( "Jun" , 17 ) ) ;
System. out. println ( queue. poll ( ) ) ;
System. out. println ( queue. poll ( ) ) ;
System. out. println ( queue. poll ( ) ) ;
}
public class Person implements Comparable < Person> {
private final String name;
private final int age;
public Person ( String name, int age) {
this . name = name;
this . age = age;
}
public String getName ( ) {
return name;
}
public int getAge ( ) {
return age;
}
@Override
public String toString ( ) {
return "(Person: " + name + ", " + age + ")" ;
}
public int compareTo ( Person o) {
return this . name. compareTo ( o. name) ;
}
}
Deque
:
Deque实现一个双端队列(Double Ended Queue) 既可以添加到队尾,也可以添加到队首;获取也是 建议调用含Last/First的方法,方便区分 public static void main ( String[ ] args) {
Deque< String> deque = new LinkedList < > ( ) ;
deque. offerLast ( "end" ) ;
deque. offerFirst ( "C" ) ;
deque. offerFirst ( "B" ) ;
deque. offerFirst ( "A" ) ;
System. out. println ( deque. pollLast ( ) ) ;
System. out. println ( deque. pollFirst ( ) ) ;
System. out. println ( deque. pollFirst ( ) ) ;
System. out. println ( deque. pollFirst ( ) ) ;
System. out. println ( deque. pollFirst ( ) ) ;
}
Stack
:
栈是一种后进先出的数据结构,计算机内存中普遍采用栈式结构 用Deque可以实现栈的功能
push():压栈 pop():出栈 peek():去栈顶元素但不出栈
public static void main ( String[ ] args) {
String s = "1 + 2 * (9 - 5)" ;
Calculator calc = new Calculator ( ) ;
Object[ ] exp = calc. compile ( s) ;
int result = calc. calculate ( exp) ;
System. out. println ( "[calculate] " + s + " => " + expressionToString ( exp) + " => " + result) ;
}
static String expressionToString ( Object[ ] exp) {
List< String> list = new ArrayList < > ( exp. length) ;
for ( Object e : exp) {
list. add ( e. toString ( ) ) ;
}
return String. join ( " " , list) ;
}
import java. util. ArrayList;
import java. util. Deque;
import java. util. LinkedList;
import java. util. List;
public class Calculator {
public Object[ ] compile ( String s) {
Object[ ] parsed = parseAsExpression ( s) ;
List< Object> output = new LinkedList < > ( ) ;
Deque< Character> stack = new LinkedList < > ( ) ;
for ( Object e : parsed) {
if ( e instanceof Integer ) {
output. add ( e) ;
} else {
char ch = ( Character) e;
switch ( ch) {
case ')' :
for ( ; ; ) {
if ( stack. isEmpty ( ) ) {
throw new IllegalStateException ( "Compile error: " + s) ;
}
char top = stack. pop ( ) ;
if ( top == '(' ) {
break ;
} else {
output. add ( top) ;
}
}
break ;
case '(' :
stack. push ( ch) ;
break ;
case '+' :
case '-' :
case '*' :
case '/' :
while ( ! stack. isEmpty ( ) ) {
char first = stack. peek ( ) ;
if ( priority ( first) >= priority ( ch) ) {
stack. pop ( ) ;
output. add ( first) ;
} else {
break ;
}
}
stack. push ( ch) ;
break ;
default :
throw new IllegalStateException ( "Compile error: " + s) ;
}
}
}
while ( ! stack. isEmpty ( ) ) {
output. add ( stack. pop ( ) ) ;
}
return output. toArray ( ) ;
}
public int calculate ( Object[ ] expression) {
Deque< Integer> stack = new LinkedList < > ( ) ;
for ( Object e : expression) {
if ( e instanceof Integer ) {
stack. push ( ( Integer) e) ;
} else {
char op = ( Character) e;
int n1 = stack. pop ( ) ;
int n2 = stack. pop ( ) ;
int r = operate ( op, n2, n1) ;
stack. push ( r) ;
}
}
return stack. pop ( ) ;
}
Object[ ] parseAsExpression ( String s) {
List< Object> list = new ArrayList < > ( ) ;
for ( char ch : s. toCharArray ( ) ) {
if ( ch >= '0' && ch <= '9' ) {
int n = Integer. parseInt ( String. valueOf ( ch) ) ;
list. add ( n) ;
} else if ( "+-*/()" . indexOf ( ch) != ( - 1 ) ) {
list. add ( ch) ;
} else if ( ch == ' ' ) {
} else {
throw new IllegalArgumentException ( "Compile error: invalid char \'" + ch + "\'" ) ;
}
}
return list. toArray ( ) ;
}
int priority ( char op) {
switch ( op) {
case '*' :
case '/' :
return 2 ;
case '+' :
case '-' :
return 1 ;
case '(' :
return 0 ;
default :
throw new IllegalArgumentException ( "bad operator: " + op) ;
}
}
int operate ( char operator, int a, int b) {
switch ( operator) {
case '+' :
return a + b;
case '-' :
return a - b;
case '*' :
return a * b;
case '/' :
return a / b;
default :
throw new UnsupportedOperationException ( ) ;
}
}
}
Set
Set<E>相当于不存储value的Map;用于去除重复元素 Set
被AbstractSet实现,又分为2个子类,HashSet和TreeSet类似Map,TreeSet实现SortedSet,有序 常用方法:
import java. util. *;
public static void main ( String[ ] args) {
List< String> list1 = Arrays. asList ( "pear" , "apple" , "banana" , "orange" , "apple" , "banana" ) ;
List< String> list2 = removeDuplicate ( list1) ;
System. out. println ( list2) ;
}
static List< String> removeDuplicate ( List< String> list) {
Set< String> set = new HashSet < > ( list) ;
return new ArrayList < String> ( set) ;
}
同样,放入Set的元素(类)要正确实现equals和hashCode方法
Map
Map是一种键-值映射表 Map被AbstractMap实现,又分为2个子类,HashMap和TreeMap HashMap不保证顺序 TreeMap实现的是SortedMap,所以可以保证按key有序 常用方法:
import java. util. *;
List< Person> list = Arrays. asList ( new Person ( "Ming" , 12 ) , new Person ( "Hong" , 15 ) , new Person ( "Jun" , 18 ) ) ;
Map< String, Person> map = new HashMap < > ( ) ;
for ( Person p : list) {
map. put ( p. getName ( ) , p) ;
}
System. out. println ( map. get ( "Jun" ) ) ;
System. out. println ( map. get ( "Mark" ) ) ;
for ( String key : map. keySet ( ) ) {
System. out. println ( key+ "-->" + map. get ( key) ) ;
}
for ( Map. Entry< String, Person> entry : map. entrySet ( ) ) {
System. out. println ( entry. getKey ( ) + "-->" + entry. getValue ( ) ) ;
}
public class Person {
private final String name;
private final int age;
public Person ( String name, int age) {
this . name = name;
this . age = age;
}
public String getName ( ) {
return name;
}
public int getAge ( ) {
return age;
}
@Override
public String toString ( ) {
return "(Person: " + name + ", " + age + ")" ;
}
}
HashMap通过计算key的hashCode定位key的存储位置,继而得到value 类似于List的contains()方法,凡是放入map的类必须重写equals()和hashCode()方法
只要参数相等即认为是相同对象,必须有相同的hashCode 只要参数不相等,则hashCode不等,避免冲突
public static void main ( String[ ] args) {
List< Person> list = Arrays. asList ( new Person ( "Ming" , 12 ) , new Person ( "Hong" , 15 ) , new Person ( "Jun" , 18 ) ) ;
Map< Person, String> map = new HashMap < > ( ) ;
for ( Person p : list) {
map. put ( p, p. getName ( ) ) ;
}
System. out. println ( map. get ( new Person ( "Jun" , 18 ) ) ) ;
}
import java. util. Objects;
public class Person {
private final String name;
private final int age;
public Person ( String name, int age) {
this . name = name;
this . age = age;
}
public String getName ( ) {
return name;
}
@Override
public 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 &&
Objects. equals ( name, person. name) ;
}
@Override
public int hashCode ( ) {
return Objects. hash ( name, age) ;
}
public int getAge ( ) {
return age;
}
@Override
public String toString ( ) {
return "(Person: " + name + ", " + age + ")" ;
}
}
Iterator迭代器
Iterator
是一个用来遍历集合中元素的接口,主要方法:
next()
:返回迭代器刚越过的元素的引用,返回值是Object,需要强制转换成自己需要的类型hasNext()
:判断容器内是否还有可供访问的元素remove()
:删除迭代器刚越过的元素
它的子接口ListIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious() 我们可以通过实现Iterable
接口,返回Iterator对象,让自己编写的类也能使用for…each循环 参考如下代码:
public static void main ( String[ ] args) throws Exception {
ReadOnlyList< String> list = new ReadOnlyList < > ( "apple" , "pear" , "orange" ) ;
for ( String s : list) {
System. out. println ( s) ;
}
}
import java. util. Iterator;
public class ReadOnlyList < E> implements Iterable < E> {
E[ ] array;
@SafeVarargs
public ReadOnlyList ( E. . . array) {
this . array = array;
}
@Override
public Iterator< E> iterator ( ) {
return new ReadOnlyIterator ( ) ;
}
class ReadOnlyIterator implements Iterator < E> {
int index = 0 ;
@Override
public boolean hasNext ( ) {
return index < ReadOnlyList. this . array. length;
}
@Override
public E next ( ) {
E e = array[ index] ;
index++ ;
return e;
}
}
}
调用者不需要知道集合内部结构,交给forEach即可以直接进行迭代!
Properties
Properties
用于读写配置文件xxx.properties.properties文件是key=value的形式,只能使用ASCII码
public static void main ( String[ ] args) throws Exception {
Properties props = new Properties ( ) ;
props. load ( Main. class . getResourceAsStream ( "/setting.properties" ) ) ;
String url = props. getProperty ( "url" ) ;
String lang = props. getProperty ( "language" ) ;
String title = props. getProperty ( "course.title" ) ;
String description = props. getProperty ( "course.description" ) ;
System. out. println ( url) ;
System. out. println ( lang) ;
System. out. println ( title) ;
System. out. println ( description) ;
}
# comment
url= https: / / www. feiyangedu. com/
language = Java
course. title= Java\u96c6\u5408\u7c7b
Collections
Collections类提供了一组工具方便的使用集合类Collection
public class Practice {
public static void main ( String[ ] args) {
List list = Arrays. asList ( "one two three four five six siven" . split ( "" ) ) ;
System. out. println ( list) ;
Collections. reverse ( list) ;
System. out. println ( list) ;
List< String> list1 = new ArrayList < > ( Arrays. asList ( "A" , "B" , "C" ) ) ;
List< String> readOnlyList = Collections. unmodifiableList ( list1) ;
System. out. println ( readOnlyList) ;
readOnlyList. add ( "X" ) ;
}
}
小结
上面大致梳理了Java中集合的相关概念和用法,主要是List,Set,Map,以及相关的队列、栈、迭代器。后面介绍了两个实用的工具,配置读取类Properties和集合操作类Collections。集合是应用非常广泛的对象容器,需要多加体会! 又是长篇大论,没办法,零基础小白只能点滴积累!