0%

Java一天学一点

当初学java的时候,偷懒没怎么学,敲的代码太少.如今又选了java进阶.
从头开始,一点一点学吧.

Only action can relieve the uneasiness. - 2020-03-18 20:20

1.如何对HashMap按键值排序

  1. 创建一个简单的HashMap,并插入一些键和值.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Map<String,Integer> aMap = new HashMap<String,Integer>(); 
    //adding keys and values
    aMap.put("Five", 5);
    aMap.put("Seven", 7);
    aMap.put("Four", 4);
    aMap.put("Eight", 8);
    aMap.put("One", 1);
    aMap.put("Two", 2);
    aMap.put("Three", 3);
  2. 利用Set entrySet(): 返回Map.Entry对象的视图集,即映像中的关键字/值对
    1
    Set<Map.Entry<String,Integer>> mapEntries = aMap.entrySet();
  3. 从上述mapEntries创建LinkedList。我们将排序这个链表来解决顺序问题
    1
    List<Map.Entry<String,Integer>> aList = new LinkedList<Map.Entry<String,Integer>>(mapEntries);
    当然 ArrayList应该也是可以的.
    1
    2
    3
    4
    5
    6
    7
    // sorting the List 
    Collections.sort(aList, new Comparator<Map.Entry<String,Integer>>(){
    @Override
    public int compare(Map.Entry<String, Integer> ele1, Map.Entry<String, Integer> ele2){
    return ele1.getValue().compareTo(ele2.getValue());
    }
    });
  4. Collections.sort()是一个内置方法,仅排序值的列表。它在Collections类中重载。这两种个方法是
    1
    2
    3
    public static <T extends Comparable<? super T>> void sort(List<T> list) 

    public static <T> void sort(List<T> list, Comparator<? super T> c)
  5. 完整代码为
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    package cn.edu.ahui;
    import java.util.*;

    public class SortHashMapByValues {
    private static void sortMapByValues(Map<String, Integer> aMap){
    Set<Map.Entry<String,Integer>> mapEntries = aMap.entrySet();
    System.out.println("Values and Keys before sorting ");
    for(Map.Entry<String,Integer> entry : mapEntries)
    System.out.println(entry.getKey() + " - "+ entry.getValue());
    //use LinkedList to sort, because insertion of elements in linked list is faster than ArrayList.
    List<Map.Entry<String,Integer>> aList = new LinkedList<Map.Entry<String,Integer>>(mapEntries);
    // sorting the List
    Collections.sort(aList, new Comparator<Map.Entry<String,Integer>>(){
    @Override
    public int compare(Map.Entry<String, Integer> ele1, Map.Entry<String, Integer> ele2){
    return ele1.getValue().compareTo(ele2.getValue());
    }
    });
    // Storing the list into Linked HashMap to preserve the order of insertion.
    Map<String,Integer> aMap2 = new LinkedHashMap<String, Integer>();
    for(Map.Entry<String,Integer> entry: aList){
    aMap2.put(entry.getKey(), entry.getValue());
    }
    // printing values after sorting of map
    System.out.println("Values and Keys after sorting ");
    for(Map.Entry<String,Integer> entry : aMap2.entrySet()){
    System.out.println(entry.getKey() + " - " + entry.getValue());
    }
    }
    public static void main(String[] args){
    Map<String,Integer> aMap = new HashMap<String,Integer>();
    //adding keys and values
    aMap.put("Five", 5);
    aMap.put("Seven", 7);
    aMap.put("Four", 4);
    aMap.put("Eight", 8);
    aMap.put("One", 1);
    aMap.put("Two", 2);
    aMap.put("Three", 3);
    sortMapByValues(aMap);
    }
    }

2.java中Comparator的用法(排序,分组)

下面是javaSE一些使用到Comparator接口的地方:

1
2
Arrays.sort(T[],Comparator<? super T> c);
Collections.sort(List<T> list,Comparator<? super T> c);
  • 使用场景
    • 排序
    • 分组

排序的例子在上面对HashMap排序已经说过了.
我们就直接看分组吧.

使用Comparator和for循环处理列表,来进行分类;通过调用者实现Comparator接口的比较逻辑,来告诉程序应该怎么比较,通过比较之后得结果来进行分组。比如生活中的拳击比赛,会有公斤级的概念,那么程序中应该实现的处理逻辑是只要两个人的体重在同一个区间则为同一组公斤级的选手。下面例子中按照手机的颜色和重量级别两个维度来进行分组,因此分组的核心逻辑其实就是比较逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package com.jason.Collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorGroup {
class Nubia {
public String name;// 手机名称
public String color;// 颜色
public int weight;// 重量

public Nubia(String name, String color, int weight) {
super();
this.name = name;
this.color = color;
this.weight = weight;
}

@Override
public String toString() {
return "Nubia [name=" + name + ",color=" + color + "色, weight=" + weight + "g]";
}
}
/**
* @Title:divider
* @author:Jason
* @date:2019年9月17日
* @Description:TODO 按条件分组
* @param <T>
* @param datas_待分组的数据List
* @param condition_是否为同一组的判断条件
* @return List<List<T>>
*/
public static <T> List<List<T>> divider(Collection<T> datas, Comparator<? super T> condition) {
// 初始化话分组List<List<T>>
List<List<T>> result = new ArrayList<List<T>>();
// 是否为同一组数据的标识
boolean isSameGroup = false;
// 遍历待分组的完整List数据
for (T data : datas) {
isSameGroup = false;
for (int j = 0; j < result.size(); j++) {
if (condition.compare(data, result.get(j).get(0)) == 0) {
isSameGroup = true;
result.get(j).add(data);
break;
}
}
if (!isSameGroup) {
// 创建分组List
List<T> groupList = new ArrayList<T>();
result.add(groupList);
groupList.add(data);
}
}
return result;
}

// 对分组的List按重量升序排列

public static void sortListNubia(List<List<Nubia>> sortNubia) {
// 对分组的List按重量升序排列
Comparator<List<Nubia>> comparator = new Comparator<List<Nubia>>() {
@Override
public int compare(List<Nubia> nb1, List<Nubia> nb2) {
return nb1.get(0).weight - nb2.get(0).weight;
}
};
Collections.sort(sortNubia, comparator);
}

public static void main(String[] args) {
// 初始化List数据
List<Nubia> list = new ArrayList<>();
list.add(new ComparatorGroup().new Nubia("努比亚z7mini", "黑金", 143));
list.add(new ComparatorGroup().new Nubia("努比亚z11mini", "黑金", 138));
list.add(new ComparatorGroup().new Nubia("努比亚红魔Mars", "黑红", 193));
list.add(new ComparatorGroup().new Nubia("努比亚红魔3 ", "黑红", 215));
list.add(new ComparatorGroup().new Nubia("努比亚X", "蓝银", 181));
list.add(new ComparatorGroup().new Nubia("努比亚布拉格 ", "蓝银", 140));
// 按颜色分组
List<List<Nubia>> byColors = divider(list, new Comparator<Nubia>() {
@Override
public int compare(Nubia nb1, Nubia nb2) {
// 按颜色分组
return nb1.color.compareTo(nb2.color);
}
});
// 按重量升序
sortListNubia(byColors);
System.out.println("按颜色分组:");
for (List<Nubia> list2 : byColors) {
System.out.println(list2);
}
// 按重量分组
List<List<Nubia>> byWeight = divider(list, new Comparator<Nubia>() {
@Override
public int compare(Nubia nb1, Nubia nb2) {
// 按重量区间
return ((nb1.weight / 30) == (nb2.weight / 30)) ? 0 : 1;
}
});
// 按重量升序
sortListNubia(byWeight);
System.out.println("按重量级分组:");
for (List<Nubia> list2 : byWeight) {
System.out.println(list2);
}
}
}

结果:

按颜色分组:
[Nubia [name=努比亚z7mini,color=黑金色, weight=143g], Nubia [name=努比亚z11mini,color=黑金色, weight=138g]]
[Nubia [name=努比亚X,color=蓝银色, weight=181g], Nubia [name=努比亚布拉格 ,color=蓝银色, weight=140g]]
[Nubia [name=努比亚红魔Mars,color=黑红色, weight=193g], Nubia [name=努比亚红魔3 ,color=黑红色, weight=215g]]
按重量级分组:
[Nubia [name=努比亚z7mini,color=黑金色, weight=143g], Nubia [name=努比亚z11mini,color=黑金色, weight=138g], Nubia [name=努比亚布拉格 ,color=蓝银色, weight=140g]]
[Nubia [name=努比亚红魔Mars,color=黑红色, weight=193g], Nubia [name=努比亚X,color=蓝银色, weight=181g]]
[Nubia [name=努比亚红魔3 ,color=黑红色, weight=215g]]

3.遍历map的四种方法及Map.entry详解

Map.entrySet() 这个方法返回的是一个Set<Map.Entry<K,V>>
Map.Entry 是Map中的一个接口,他的用途是表示一个映射项(里面有Key和Value),而Set<Map.Entry<K,V>>表示一个映射项的Set。Map.Entry里有相应的getKey和getValue方法,即JavaBean,让我们能够从一个项中取出Key和Value。

下面是遍历Map的四种方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.jason.Collection;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class CollectionDemo {
public static void main(String[] args) {

Map<String, String> map = new HashMap<String, String>();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");

// 第一种:普遍使用,二次取值
System.out.println("通过Map.keySet遍历key和value:");
for (String key : map.keySet()) {
System.out.println("key= " + key + " and value= " + map.get(key));
}

// 第二种
System.out.println("通过Map.entrySet使用iterator遍历key和value:");
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}

// 第三种:推荐,尤其是容量大时
System.out.println("通过Map.entrySet遍历key和value");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}

// 第四种
System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
for (String v : map.values()) {
System.out.println("value= " + v);
}
}
}

看HashMap的源代码:会发现,HashMap的底层实现用的是一个Entry数组.
我们在HashMap的源码的674行发现了Entry的定义,原来他是HashMap的一个内部类,并且实现了Map.Entry接口
我们再看一下Map.Entry这个接口是怎么定义的,发现原来他是Map的一个内部接口并且定义了一些方法
原来Entry实现的Map.Entry接口里面定义了getKey(),getValue(),setKey(),setValue()等方法相当于一个javaBean,对键值对进行了一个封装便于后面的操作,从这里我们其实也可以联想到不光是HashMap,譬如LinkedHashMap,TreeMap 等继承自map的容器存储key-value对都应该使用的是Entry只不过组织Entry的形式不一样,HashMap用的是数组加链表的形式,LinkedHashMap用的是链表的形式,TreeMap应该使用的二叉树的形式.想多了解一下的可以查看源码.

转自

操作系统 Homework: Shell

Homework: shell

通过此次作业,将会了解到 Shell 的工作原理,以及类 Linux 系统的新进程到底是如何产生的。

阅读全文 »

Threads and Locking

题目来源Threads and Locking
本次作业主要讲的是并行作业,以及并行作业中互斥锁(P,V问题)的相关知识。

阅读全文 »

对五个数排序最少需要7次.

今个儿,算法老师上课给我们出的一道题,老师只是告诉我们7次,也没说具体怎么个过程.
上网查了查也是看懂了吧
本文介绍一个对5个数进行排序的方法,仅使用7次比较。假设要排序的数为a,b,c,d,e。

首先将a,b进行比较,假设结果为a<b,再将c,d进行比较,假设结果为c<d;然后将两组数的较大者进行比较(即比较b,d),假设结果为b<d,于是就有下面的关系,箭头的关系表示“<”,即”小于”,至此,已经进行了三次比较。

即:a<b<d,c<d

现在将e插入到{a,b,d}的适当位置,采用二分查找法寻找查找位置时,只需要两次比较——先同b比较,然后再同a或d比较。将e插入到{a,b,d}时,一共有四种情况

e<a<b<d,
a<e<b<d,
a<b<e<d,
a<b<d<e,
c<d

在这四中情况中,要将c插入到由[abcd]组成的序列中最多只需要两次比较。同样使用二分法寻找插入位置。以第一种情况为例:c首先同a比较,如果大于a,再同b比较,如果大于b,则不会再同d比较,因为我们在之前已经知道c<d。

所以 3 + 2 + 2 = 7,一共是7次比较

计网马上要考试了,之前从头看了遍网课,整理了点知识点和习题. 挑挑拣拣选一些考纲上的内容也来一个
一天一遍,预防失眠(yjn_语录)

阅读全文 »