马太效应 发表于 2017-8-28 23:12:37

Java暑期学习Day41

本帖最后由 马太效应 于 2017-8-28 23:12 编辑

今天是第41天,之前准备旅行+出发体验花了十来天的时间,也有了一些新的感悟{:10_335:}
如今离开学还有几天,继续暑期学习~等开了学,抽空再来记录的话,就是日常学习笔记啦~
越努力越幸运,希望我可以调剂好娱乐与学习,每一天都过得充实、有意义{:10_298:}

static/image/hrline/2.gif
①Comparable和Comparator
A.先从API了解大概
1.java.lang
接口 Interface Comparable<T>
此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。


对于类 C 的每一个 e1 和 e2 来说,当且仅当 (e1.compareTo((Object)e2) == 0) 与 e1.equals((Object)e2) 具有相同的布尔值时,类 C 的自然排序才叫做与 equals 一致。
注意,null 不是任何类的实例,即使 e.equals(null) 返回 false,e.compareTo(null) 也会抛出 NullPointerException。


强烈推荐(虽然不是必需的)使自然排序与 equals 一致。这是因为在使用其自然排序与 equals 不一致的元素(或键)时,没有显式比较器的有序集合(和有序映射表)行为表现“怪异”。尤其是,这样的有序集合(或有序映射表)违背了根据 equals 方法定义的集合(或映射表)的常规协定。
例如,如果将两个键 a 和 b 添加到一个没有使用显式比较器的有序集合中,使得 (!a.equals((Object)b) && a.compareTo((Object)b) == 0),则第二个 add 操作返回 false(有序集合的大小没有增加),因为从有序集合的角度来看,a 和 b 是等效的。


实际上,所有执行比较的 Java 核心类都具有 equals 一致的自然排序。java.math.BigDecimal 是个例外,它的自然排序把值相等但精确度不同的 BigDecimal 对象(比如 4.0 和 4.00)等同起来。
为了向数学上倾斜,在给定 C 类的基础上定义自然排序的关系 如下:
{(x, y) such that x.compareTo((Object)y) <= 0}。
整体排序的 quotient 是:
      {(x, y) such that x.compareTo((Object)y) == 0}。
它直接遵循 compareTo 的协定,商是 C 的等价关系,自然排序是 C的整体排序。当我们说类的自然排序与 equals 一致 时,是指自然排序的商是由类的 equals(Object) 方法定义的等价关系。
    {(x, y) such that x.equals((Object)y)}。

此接口是 Java Collections Framework 的成员。


2.java.util
Interface Comparator<T>
参数类型
T - 可比较此比较器的对象类型

所有已知实现类:
Collator , RuleBasedCollator
Functional Interface:
这是一个功能界面,因此可以用作lambda表达式或方法引用的赋值对象。
@FunctionalInterface
public interface Comparator<T>比较功能,对一些对象的集合施加了一个整体排序 。 可以将比较器传递给排序方法(如Collections.sort或Arrays.sort ),以便对排序顺序进行精确控制。 比较器还可以用来控制某些数据结构(如顺序sorted sets或sorted maps ),或对于不具有对象的集合提供的排序natural ordering 。

通过比较c上的一组元素S的确定的顺序对被认为是与equals一致当且仅当c.compare(e1, e2)==0具有用于S每e1和e2相同布尔值e1.equals(e2)。
当使用能够强制排序不一致的比较器时,应注意使用排序集(或排序图)。 假设具有显式比较器c的排序集(或排序映射)与从集合S中绘制的元素(或键) 一起使用 。
{:10_327:}
B.代码中理解常见用法

1.
package collection;
import java.util.*;
/*
*
* Collections的sort()方法要求被排序的对象必须操作java.lang.Comparable接口
* 这个接口里的compareTo()方法必须返回大于0、等于0或小于0的数
*/
class Account2 implements Comparable<Account2>{
private String name;
private String number;
private intbalance;

Account2 (String name,String number,int balance){
        this.balance=balance;
        this.name=name;
        this.number=number;

}
@Override
public String toString(){
        return String.format("Account2(%s,%s,%d)", name,number,balance);
       
}

        @Override
        public int compareTo(Account2 other) {
                return this.balance-other.balance;
        }

}
public class Sort3{
        public static void main(String[] args) {
                List accounts=Arrays.asList(
                        new Account2("a","x1",1000),
                        new Account2("b","x2",500),
                        new Account2("c","x3",200)               
                );
                Collections.sort(accounts);
                /*
               * Collections的sort()方法在取得a对象和b对象进行比较时,
               * 会先将a对象扮演为Comparable(也因此若对象没有操作Comparable,
               * 将会抛出ClassCastException -
               * 如果指定的对象的类型阻止它与该对象进行比较),
               * 然后调用a.compareTo(b),如果a对象顺序上小于b对象则返回小于0的值,
               * 若顺序上相等则返回0,若顺序上a大于b则返回大于0的值。
               *
               */
                System.out.println(accounts);
        }
}结果是——



2.<b>package collection;

import java.util.*;
/*
* int compare(T o1,T o2)比较其两个参数的顺序。
* 返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数。
*
* 将compareTo()返回的值乘上-1,就可以调换顺序。
*/

class StringComparator implements Comparator<String> {

        @Override
        public int compare(String o1, String o2) {
                return -o1.compareTo(o2);
        }

}

public class Sort4 {
        public static void main(String[] args) {
                List<String> words = Arrays.asList("B", "X", "A", "M", "F", "W", "O");
                Collections.sort(words, new StringComparator());
                System.out.println(words);

        }

}</b>
结果是——


②键值对应的Map(简单介绍)
<采用键-值对的存储方式,长度可动态改变>


1.映射(Map)是一个存储键、值对的对象。给定一个键,可以查询到它的值,键和值都是对象。
2.键必须是唯一的,值可以重复。
3.有些映射可以接收null键和null值,有的不行。
4.下面的接口支持映射:



接口 描述
Map 映射唯一关键字给值
Map.Entry 描述映射中的元素(关键字/值对)。这是Map的一个内部类
SortedMap
继承于Map,扩展Map以便关键字按升序保持



5.public interface Map<K,V>
将键映射到值的对象。
地图不能包含重复的键; 每个键可以映射到最多一个值。
这个接口取代了Dictionary类,它是一个完全抽象的类而不是接口。


6.键(key)是以后用于检索值的对象。给定一个键和一个值,可以存储这个值到一个Map对象中,以后可以使用对应的键来检索它。


7.Map接口中定义的常用方法:
int size()
返回此地图中键值映射的数量。 如果地图包含超过Integer.MAX_VALUE个元素,则返回Integer.MAX_VALUE 。
结果
该地图中键值映射的数量


boolean isEmpty()
如果此地图不包含键值映射,则返回 true 。
结果
true如果此映射不包含键值映射


boolean containsKey(Object key)
如果此映射包含指定键的映射,则返回true 。 更正式地,返回true当且仅当该地图包含关键字k的映射,使得(key==null ? k==null : key.equals(k)) 。
(最多可以有一个这样的映射。)
参数
key - 要在此地图中存在的密钥要进行测试
结果
true如果此映射包含指定键的映射
异常
ClassCastException - 如果密钥对于该地图是不合适的类型( optional )
NullPointerException - 如果指定的键为空,并且此映射不允许空键( optional )


Set<Map.Entry<K,V>> entrySet()
返回此地图中包含的映射的Set视图。 该集合由地图支持,因此对地图的更改将反映在集合中,反之亦然。
如果在集合中的迭代正在进行时修改映射(除了通过迭代器自己的remove操作,或者通过迭代器返回的映射条目上的setValue操作),迭代的结果是未定义的。 该组支持元件移除,即从映射中相应的映射,经由Iterator.remove,Set.remove,removeAll,retainAll和clear操作。 它不支持add或addAll操作。
结果
该地图中包含的映射的集合视图


8.Map.Entry接口代表映射项(键-值对)类型,是Map的嵌套类型
java.util
Interface Map.Entry<K,V>


③HashMap及常用API
1.public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
基于哈希表的实现的Map接口。 此实现提供了所有可选的地图操作,并允许null的值和null键。 ( HashMap类大致相当于Hashtable ,除了它是不同步的,并允许null)。


2.构造方法

Constructor and Description
HashMap()
构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。
HashMap(int initialCapacity)
构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。
HashMap(int initialCapacity, float loadFactor)
构造一个空的 HashMap具有指定的初始容量和负载因子。
HashMap(Map<? extends K,? extends V> m)
构造一个新的 HashMap与指定的相同的映射 Map 。


HashMap实现Map并扩展AbstractMap,本身并没有增加任何新的方法。


散列映射不保证它的元素的顺序,元素加入散列映射的顺序不一定是它们被迭代读出的顺序。




页: [1]
查看完整版本: Java暑期学习Day41