Java集合(一)

List
  简介
  常用方法
  ArrayList VS LinkedList
  遍历List
  List和Array转换
    List转为Array
    Array转为List
  重写equals方法
  总结
Map
  映射
  遍历Map
  HashMap
  SortedMap
  equals()和hashCode()方法
  总结
Properties
  读取配置
  总结

List

简介

List是一种有序链表:

  • List内部按照放入元素的先后顺序存放
  • 每个元素都可以通过索引确定自己的位置
  • 类似数组,但大小可变
常用方法
  • void add(E e) 在末尾添加一个元素
  • Void add(int index, E e) 在指定索引处添加一个元素
  • int remove(int index) 删除指定索引的元素
  • int remove(Object e) 删除某个元素
  • E get(int index) 获取指定索引的元素
  • int size() 获取链表大小(包含元素的个数)
  • boolean contains(Object o) 是否包含某个元素
  • int indexOf(Object o) 某个元素的索引位置
ArrayList VS LinkedList

在这里插入图片描述

遍历List
  • 使用get(int index)
List<String> list = ...
for (int i=0; i<list.size(); i++) {
  	String s = list.get(i);
}
  • 使用Iterator
List<String> list = ...
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
  	String s = it.next();
}
  • 使用foreach
List<String> list = ...
for (String s : list) {
  	...
}
List和Array转换
List转为Array
  • Object[] toArray()
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Object[] array = list.toArray();
// {1, 2, 3}
  • T[] toArray(T[] a)
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Integer[] array = list.toArray(new Integer[3]);
// Integer[] {1, 2, 3}
Number[] ns = list.toArray(new Number[3]);
// Number[] {1, 2, 3}

Array转为List
  • List Arrays.asList(T…a)
Integer[] array = {1, 2, 3};
List<Integer> list = Array.asList(array);
// 返回的list不是ArrayList,是一个List对象,只读不可写
list.add(4); // UnsupportedOperationException

// 如果想转换成一个ArrayList对象,可以创建一个新的ArrayList对象,然后把List对象的数据都添加进去
List<Integer> arrayList = new ArrayList<>();
arrayList.addAll(list);

// 代码简写为
Integer[] array = {1, 2, 3}
List<Integer> arrayList = new ArrayList(Arrays.asList(array));
重写equals方法
@Override
public boolean equals(Object o) {
  	if (this == o) {
      	return true;
    }
    if (o == null || getClass() != o.getClass()) {
      	return false;
    }
    Score score1 = (Score) o;
    return score == score1.score && Objects.equals(name, score1.name);
}
总结

List的特点:

  • 按索引顺序访问的长度可变的链表
  • 优先使用ArrayList而不是LinkedList
  • 可以直接使用for…each遍历
  • 可以和Array相互转换

如果要在List中查找元素:

  • List的实现类通过元素的equals方法比较两个元素
  • 放入的元素必须正确覆写equals方法(JDK提供的String、Integer等已经覆写了equals方法)
  • 编写equals方法可借助Objects.equals()判断

如果不在List中查找元素:

  • 不必覆写equals方法

Map

映射

Map<K, V>是一种键-值(Key-Value)映射表:

  • 可以通过Key快速查找Value(元素)
Map<String, Student> map = ...
Student stu = map.get("XiaoMing");
  • V put(K key, V value) 把Key-Value放入Map
  • V get(K key) 通过Key获取Value
  • boolean containsKey(K key) 判断Key是否存在
遍历Map
  • 遍历Key可以使用for…each循环遍历keySet()
Map<String, Integer> map = ...
for (String key : map.keySet()) {
  	Integer value = map.get(key);
}
  • 同时遍历Key和Value可以使用for…each循环遍历entrySet()
Map<String, Integer> map = ...
for (Map.Entry<String, Integer> entry : map.entrySet()) {
  	String key = entry.getKey();
  	Integer value = entry.getValue(); 
}
HashMap

最常用的实现类是HashMap,HashMap内部存储不保证有序

  • 遍历时的顺序不一定是put放入的顺序,也不一定是Key的排序顺序
Map<String, Integer> map = new HashMap<>();
map.put("A", 59);
map.put("B", 78);
map.put("C", 89);
for (String key : map.keySet()) {
		System.out.println(key + "->" + map.get(key));
}
// B -> 78	A -> 59  C -> 89
SortedMap

SortedMap保证遍历时以Key的顺序排序

  • SortedMap的实现类是TreeMap
Map<String, Integer> map = new TreeMap<>();
map.put("A", 59);
map.put("B", 78);
map.put("C", 89);
for (String key : map.keySet()) {
		System.out.println(key + "->" + map.get(key));
}
// 	A -> 59  B -> 78  C -> 89

自定义排序需要创建TreeMap时传入一个Comparator

Map<String, Integer> map = new TreeMap<>(new Comparator<String>() {
  	public int compare(String o1, String o2) {
      	// 倒序
      	return o2.compareTo(o1);
    }
});
map.put("A", 59);
map.put("B", 78);
map.put("C", 89);
for (String key : map.keySet()) {
		System.out.println(key + "->" + map.get(key));
}
// C -> 89   B -> 78 	A -> 59
equals()和hashCode()方法

正确使用Map必须保证:

  • 作为Key的对象必须正确覆写equals()方法,例如:String、Integer…
class Person {
  	private String name;
  	private int age;
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj instanceof Person) {
						Person p = (Person)obj;
          	return Objects.equals(this.name, p.name) && this.age == p.age;
        }
      	return false;
    }
}
  • 作为Key的对象必须正确覆写hashCode()方法:
    • 如果两个对象相等,则两个对象的hashCode()必须相等
    • 如果两个对象不相等,则两个对象的hashCode() 不需要相等
public int hashCode() {
  	// 保证name和age相同时,两个对象时相同的
  	return Objects.hash(this.name, this.age);
}

如果一个对象覆写了equals()方法,就必须正确覆写hashCode()方法:

  • 如果a.equals(b) == true, 则a.hashCode() == b.hashCode()
  • 如果a.equals(b) == false, 则a和b的hashCode()尽量不要相等
总结
  • Map<K, V> 是一种映射表,可以通过Key快速查找Value
  • 可以通过for…each遍历keySet()
  • 可以通过for…each遍历entrySet()
  • 需要对Key排序时使用TreeMap
  • 通常使用HashMap
  • 作为Key的对象必须正确覆写equals和hashCode方法
  • 一个类如果覆写了equals,就必须覆写hashCode方法
  • hashCode可以通过Objects.hash()辅助方法实现

Properties

读取配置

Properties用来读取配置:

  • .properties文件只能使用ASCII编码
  • 可以从文件系统读取.properties文件
// 获取文件路径
String path = "C:\\conf\\setting.properties";
// 创建Properties对象
Properties props = new Properties();
// 加载文件
props.load(new FileInputStream(path));
// 读取配置
String url = props.getProperty("url");
// 设置默认值,当key不存在是返回默认值
String desc = props.getProperty("description", "default description");
  • 可以从ClassPath读取.properties文件
Properties props = new Properties();
// 从ClassPath下读取文件
props.load(getClass().getResourceAsStream("/common/setting.properties"));
// 读取配置
String url = props.getProperty("url");
// 设置默认值,当key不存在是返回默认值
String desc = props.getProperty("description", "default description");
  • 可以读取多个.properties文件

  • 后读取的Key-Value会覆盖已读取的Key-Value

Properties props = new Properties();
// 从ClassPath下加载配置
props.load(getClass().getResourceAsStream("/common/setting.properties"));
// 从文件中读取加载配置
props.load(new FileInputStream("C:\\conf\\setting.properties"));

// 读取配置
String url = props.getProperty("url");
// 设置默认值,当key不存在是返回默认值
String desc = props.getProperty("description", "default description");

Properties实际上是从Hashtable派生:

  • String getProperty(String key)
  • void setProperty(String key, String Value)
  • Object get(Object key) 继承下来的方法,不要使用
  • void put(Object key, Object value) 继承下来的方法,不要使用
总结
  • Properties用于读写配置文件xxx.properties
  • .properties文件只能使用ASCII编码
  • 可以从ClassPath或文件系统读取.properties文件
  • 读写Properties时:
    • 仅使用getProperty() / setProperty()方法
    • 不要使用继承而来的get() / put() 方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章