日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

java icomparer_集合数据处理(C#、JavaScript 和 Java)

發布時間:2025/4/5 C# 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java icomparer_集合数据处理(C#、JavaScript 和 Java) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java 丟了好多年,最近在揀起來,首先當然是了解這么多年來它的變化,于是發現了 Java 8 的java.util.stream。在學習和試驗的過程中,相比較于 C# 和 javascript,有那么些心得,作文以記之。

早些時間寫過一篇《ES6 的 for..of 和 Generator,從偽數組 jQuery 對象說起》,和這個主題有點關系。其實我記得還有一篇講 C# 的,沒找到,也許只是想過,沒寫成,成了虛假記憶。

前言

之所以把 C#、JavaScript 和 Java 三種語言的實現寫在一起,主要是為了放在一起有一個類比,可能會有助于理解。

集合數據

C# 的集合數據基類是 Collection,它實現了 ICollection接口,而 ICollection 又從 IEnumerable 接口繼承——實際上要討論的內容都基于 IEnumerable 接口。另外還有一個非泛型的 IEnumerable 接口,不過建議大家盡量使用泛型,所以這個非泛型的接口就當我沒說。順便提一句,數組也是實現了 IEnumerable 接口的。System.Linq 中提供的擴展大大方便了集合處理過程。

JavaScript 最常見的集合數據類型就是數組,自 ES6 發布以后,這個范圍擴展到了 iterable 對象。不過這里要討論的內容都是在 Array.prototype 中實現的。除此之外,underscore、lodash 這些第三方庫中也實現了很多集合數據處理的方法,但不在本文討論內容之內。

Java 的集合類型由 Collection 接口定義。本文討論的內容是 Java 8 的特性,在 java.util.stream 包中實現,由 Collection.stream() 引入。

示例語言版本

后面示例中的部分 C# 語句可能需要支持 6.0 語言版本的編譯器,如 Visual Studio 2015 或者 Visual Studio "15"

JavaScript 代碼都使用了 ES6 語法,目前大部分瀏覽器支持,Node 5 也完全支持。

Java 要求 Java 8(或 1.8)版本

遍歷

問題提出

給定一個名稱列表,數組類型, ["Andy", "Jackson", "Yoo"],要求遍歷出到的控制臺。

C# 的遍歷

對于集合來說,最常用的就是遍歷,不過 for,foreach, while 之類大家都耳熟能詳了,不再多說。這里說的是 forEach() 方法。

很遺憾,C# 的 Linq 擴展 里沒有提供 ForEach() 方法,不過 All(IEnumerable, Func) 和 Any(IEnumerable, Func) 都可以代替。這兩個方法的區別就在于第二個參數 Func 的返回值。這兩個方法都會遍歷集合,對集合中的每個元素依次調用第二個參數,Func 所指的委托方法,并檢查其返回值,All() 檢查到 false 中止遍歷,而 Any() 檢查到 true 中止遍歷。

All() 的意思是,所有元素都符合條件則返回 true,所有只要有一個不符合條件,返回了 false,則中止遍歷,返回 false;Any() 的意思是只要發現有元素符合條件則返回 true。

Func 是一個公用委托。Func<...> 系列公用委托都用于委托帶有返回值的的方法,所有 Func<... tresult> 都是最后一個參數 TResult 代表返回值類型。

因此,C# 的遍歷輸出可以這樣實現

string[] names = { "Andy", "Jackson", "Yoo" };

names.All(name => {

Console.WriteLine(name);

return true;

});

string[] names = { "Andy", "Jackson", "Yoo" };

names.Any(name => {

Console.WriteLine(name);

return false;

});

有 Lambda 就是好

JavaScript 的遍歷

JavaScript 的 Array 實現了 forEach 實例方法,即 Array.prototype.forEach()。

對于 JavaScript 的數組,可以這樣遍歷

var names = ["Andy", "Jackson", "Yoo"];

names.forEach(name => {

console.log(name);

});

對于 JavaScript 的偽數組,可以這樣

var names = {

0: "Andy",

1: "Jackson",

2: "Yoo",

length: 3

};

[].forEach.call(names, name => {

console.log(name);

});

jQuery 的遍歷

jQuery 是一個常用的 JavaScript 庫,它封裝的對象都是基于偽數組的,所以 jQuery 中經常用到遍歷。除了網頁元素集合外,jQuery 也可以遍歷普通數組,有兩種方式

可以直接把數組作為第一個參數,處理函數作為第二個參數調用 $.each()。

const names = ["Andy", "Jackson", "Yoo"];

$.each(names, (i, name) => {

console.log(name);

});

也可以把數組封裝成一個 jQuery 對象($(names)),再在這個 jQuery 對象上調用 eash() 方法。

const names = ["Andy", "Jackson", "Yoo"];

$(names).each((i, name) => {

console.log(name);

});

兩種方法的處理函數都一樣,但是要注意,這和原生 forEach() 的處理函數有點不同。jQuery 的 each() 處理函數,第一個參數是序號,第二個參數是數組元素;而原生 forEach() 的處理函數正好相反,第一個參數是數組元素,第二個參數才是序號。

另外,$.each() 對偽數組同樣適用,不需要通過 call() 來調用。

Java 的遍歷

String[] names = { "Andy", "Jackson", "Yoo" };

List list = Arrays.asList(names);

list.forEach(name -> {

System.out.println(name);

});

過濾(篩選)數據

問題提出

給出一組整數,需要將其中能被 3 整除選出來

[46, 74, 20, 37, 98, 93, 98, 48, 33, 15]

期望結果

[93, 48, 33, 15]

C# 中過濾使用 Where() 擴展

int[] data = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };

int[] result = data.Where(n => n % 3 == 0).ToArray();

注意:Where() 的結果即不是數組也不是 List,需要通過 ToArray() 生成數組,或者通過 ToList() 生成列表。Linq 要在 ToArray() 或者 ToList() 或者其它某些操作的時候才會真正遍歷,依次執行 Where() 參數提供的那個篩選函數。

const data = [46, 74, 20, 37, 98, 93, 98, 48, 33, 15];

const result = data.filter(n => {

return n % 3 === 0;

});

Java 中可以通過 java.util.stream.IntStream.of() 來從數組生成 stream 對象

final int[] data = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };

int[] result = IntStream.of(data)

.filter(n -> n % 3 == 0)

.toArray();

需要注意的是,Arrays.asList(data).stream() 看起來也可以生成 stream 對象,但是通過調試會發現,這是一個 Stream 而不是 Stream。原因是 asList(T ...a) 其參數可變參數,而且要求參數類型是類,所以 asList(data) 是把 data 作為一個 int[] 類型參數而不是 int 類型的參數數據。如果要從 int[] 生成 List,還得通過 IntStream 來處理

List list = IntStream.of(data)

.boxed()

.collect(Collectors.toList());

映射處理

映射處理是指將某種類型的集合,將其元素依次映射成另一種類型,產生一個新類型的集合。新集合中的每個元素都與原集中的同樣位置的元素有對應關系。

問題提出

這里提出一個精典的問題:成績轉等級,不過為了簡化代碼(switch 或多重 if 語句代碼比較長),改為判斷成績是否及格,60 分為及格線。

偷個懶,就用上個問題的輸入 [46, 74, 20, 37, 98, 93, 98, 48, 33, 15],

期望結果:

["REJECT","PASS","REJECT","REJECT","PASS","PASS","PASS","REJECT","REJECT","REJECT"]

C# 通過 Select() 來進行映射處理。

int[] scores = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };

string[] levels = scores

.Select(score => score >= 60 ? "PASS" : "REJECT")

.ToArray();

JavaScript 通過 Array.prototype.map 來進行映射處理。

const scores = [46, 74, 20, 37, 98, 93, 98, 48, 33, 15];

const levels = scores.map(score => {

return score >= 60 ? "PASS" : "REJECT";

});

Java 的 Stream 提供了 mapToObj() 等方法處理映射

final int[] scores = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };

String[] levels = IntStream.of(scores)

.mapToObj(score -> score >= 60 ? "PASS" : "REJECT")

.toArray(String[]::new);

與“篩選”示例不同,在“篩選”示例中,由于篩選結果是 IntStream,可以直接調用 InStream::toArray() 來得到 int[]。

但在這個示例中,mapToObj() 得到的是一個 Stream,類型擦除后就是 Stream,所以 Stream::toArray() 默認得到的是一個 Object[] 而不是 String[]。如果想得到 String[],需要為 toArray() 指定 String[] 的構造函數,即 String[]::new。

生成查找表(如哈希表)

查找表在數據結構里的意義還是比較寬的,其中通過哈希算法實現的稱為哈希表。C# 中通常是用 Directory,不過它是不是通過哈希實現我就不清楚了。不過 Java 中的 HashMap 和 Hashtable,從名稱就看得出來是實現。JavaScript 的字面對象據稱也是哈希實現。

提出問題

現在有一個姓名列表,是按學號從 1~7 排列的,需要建立一個查找到,使之能通過姓名很容易找到對應的學號。

["Andy", "Jackson", "Yoo", "Rose", "Lena", "James", "Stephen"]

期望結果

Andy => 1

Jackson => 2

Yoo => 3

Rose => 4

Lena => 5

James => 6

Stephen => 7

C# 使用 ToDictionary()

string[] names = { "Andy", "Jackson", "Yoo", "Rose", "Lena", "James", "Stephen" };

int i = 1;

Dictionary map = names.ToDictionary(n => n, n => i++);

C# Linq 擴展提供的若干方法都沒有將序號傳遞給處理函數,所以上例中采用了臨時變量計數的方式來進行。不過有一個看起來好看一點的辦法,用 Enumerable.Range() 先生成一個序號的序列,再基于這個序列來處理

string[] names = { "Andy", "Jackson", "Yoo", "Rose", "Lena", "James", "Stephen" };

IEnumerable indexes = Enumerable.Range(0, names.Length);

Dictionary map = indexes.ToDictionary(i => names[i], i => i + 1);

JavaScript 的兩種處理辦法

JavaScript 沒有提供從 [] 到 {} 的轉換函數,不過要做這個轉換也不是好麻煩,用 forEach 遍歷即可

var map = (function() {

var m = {};

names.forEach((name, i) => {

m[name] = i + 1;

});

return m;

})();

為了不讓臨時變量污染外面的作用域,上面的示例中采用了 IEFE 的寫法。不過,如果用 Array.prototype.reduce 則可以讓代碼更簡潔一些

var map = names.reduce((m, name, i) => {

m[name] = i + 1;

return m;

}, {});

Java 的處理函數也沒有傳入序號,所以在 Java 中的實例和 C# 類似。不過,第一種方法不可用,因為 Java Lambda 的實現相當于是匿名類對接口的實現,只能訪問局部的 final 變量,i 要執行 i++ 操作,顯然不是 final 的,所以只能用第二種辦法

final String[] names = { "Andy", "Jackson", "Yoo", "Rose", "Lena", "James", "Stephen" };

Map map = IntStream.range(0, names.length)

.boxed()

.collect(Collectors.toMap(i -> names[i], i -> i + 1));

我只能說 .boxed() 是個大坑啊,一定要記得調。

匯總和聚合處理

匯總處理就是合計啊,平均數啊之類的,使用方式都差不多,所以以合計(Sum)為例。

匯總處理其實是聚合處理的一個特例,所以就同一個問題,再用普通的聚合處理方式再實現一次。

問題提出

已知全班成績,求班總分,再次用到了那個數組

[46, 74, 20, 37, 98, 93, 98, 48, 33, 15]

期望結果:562

C# 的實現

C# 可以直接使用 Sum() 方法求和

int[] scores = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };

int sum = scores.Sum();

聚合實現方式(用 Aggregate())

int[] scores = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };

int sum = scores.Aggregate(0, (total, score) => {

return total + score;

});

聚合實現方式要靈活得多,比如,改成乘法就可以算階乘。當然用于其它更復雜的情況也不在話下。前面生成查找表的 JavaScript 部分就是采用聚合來實現的。

JavaScript 都是通過聚合來實現的

const scores = [46, 74, 20, 37, 98, 93, 98, 48, 33, 15];

const sum = scores.reduce((total, score) => {

return total + score;

}, 0);

注意 C# 的初始值在前,JavaScript 的初始值在后,這是有區別的。參數順序嘛,注意一下就行了。

Java 中使用 Stream::reduce 進行聚合處理

IntStream 提供了 sum() 方法

final int[] scores = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };

final int sum = IntStream.of(scores).sum();

同樣也可以用 reduce 處理

final int[] scores = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };

final int sum = IntStream.of(scores)

.reduce(0, (total, score) -> total + score);

綜合應用

問題提出

已知全班 7 個人,按學號 從 1~7 分別是

["Andy", "Jackson", "Yoo", "Rose", "Lena", "James", "Stephen"]

這 7 個人的成績按學號序,分別是

[66, 74, 43, 93, 98, 88, 83]

有 Student 數組結構

Student {

number: int

name: string

score: int

}

要求得到全班 7 人的 student 數組,且該數組按分數從高到低排序

C# 實現

sealed class Student {

public int Number { get; }

public string Name { get; }

public int Score { get; }

public Student(int number, string name, int score) {

Number = number;

Name = name;

Score = score;

}

public override string ToString() => $"[{Number}] {Name} : {Score}";

}

Student[] students = Enumerable.Range(0, names.Length)

.Select(i => new Student(i + 1, names[i], scores[i]))

.OrderByDescending(s => s.Score)

.ToArray();

注意 C# 中排序有 OrderBy 和 OrderByDescending 兩個方法,一般情況下只需要給一個映射函數,從原數據里找到要用于比較的數據即可使用其 >、< 等運算符進行比較。如果比例起來比較復雜的,需要提供第二個參數,一個 IComparer 的實現

JavaScript 實現

class Student {

constructor(number, name, score) {

this._number = number;

this._name = name;

this._score = score;

}

get number() {

return this._number;

}

get name() {

return this._name;

}

get score() {

return this._score;

}

toString() {

return `[${this.number}] ${this.name} : ${this.score}`;

}

}

const names = ["Andy", "Jackson", "Yoo", "Rose", "Lena", "James", "Stephen"];

const scores = [66, 74, 43, 93, 98, 88, 83];

var students = names

.map((name, i) => new Student(i + 1, name, scores[i]))

.sort((a, b) => {

return b.score - a.score;

});

JavaScript 的排序則是直接給個比較函數,根據返回的數值小于0、等于0或大于0來判斷是小于、等于還是大于。

Java 實現

final class Student {

private int number;

private String name;

private int score;

public Student(int number, String name, int score) {

this.number = number;

this.name = name;

this.score = score;

}

public int getNumber() {

return number;

}

public String getName() {

return name;

}

public int getScore() {

return score;

}

@Override

public String toString() {

return String.format("[%d] %s : %d", getNumber(), getName(), getScore());

}

}

final String[] names = { "Andy", "Jackson", "Yoo", "Rose", "Lena", "James", "Stephen" };

final int[] scores = { 66, 74, 43, 93, 98, 88, 83 };

Student[] students = IntStream.range(0, names.length)

.mapToObj(i -> new Student(i + 1, names[i], scores[i]))

.sorted((a, b) -> b.getScore() - a.getScore())

.toArray(Student[]::new);

總結

以上是生活随笔為你收集整理的java icomparer_集合数据处理(C#、JavaScript 和 Java)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 99草在线视频 | 亚洲一区二区免费 | 麻豆传媒网站入口 | 日本一区二区在线播放 | 中文字幕五区 | 91人人爱| 国产精品午夜未成人免费观看 | 99精品中文字幕 | 国产亚洲欧美精品久久久久久 | 亚洲爱爱爱 | 精品人妻天天爽夜夜爽视频 | 色漫| 夜夜操操操 | 亚洲成年人在线 | 国产自偷自拍视频 | 国产精品88 | 日韩精品电影一区 | 精品成人一区二区三区 | 亚洲午夜精品一区二区三区他趣 | 四川话毛片少妇免费看 | 婷婷色基地| 欧美在线一二 | 欧美黄色片免费看 | 久久精品国产亚洲av香蕉 | 亚洲成人网av | 在线观看污污视频 | 精品视频在线观看一区二区 | 日本视频精品 | 少妇人妻一级a毛片 | 亚洲久久色| caobi视频 | 婷婷久久久久久 | 国产素人在线观看 | 一区二区久久久 | 奇米影视久久 | 亚洲一区二区三区网站 | av福利影院 | 精品国产久 | 久久婷婷五月综合色国产香蕉 | 777奇米色 | 午夜激情国产 | 国产高清在线 | 18av在线播放 | 国产精品99一区二区三区 | 国产精品无码一区二区桃花视频 | 久久久久久久久艹 | 成人在线观看一区二区 | 国产人成 | 国产精品一区麻豆 | 欧美区在线 | 亚洲高清精品视频 | 精品国产制服丝袜高跟 | 亚洲av无码一区二区三区性色 | 黄色专区| 国产欧美一区在线观看 | 最新日韩av在线 | 男人久久天堂 | 亚洲激情六月 | 野外吮她的花蒂高h在线观看 | proumb性欧美在线观看 | 正在播放木下凛凛88av | 短篇山村男同肉耽h | 亚洲精品国产精品国自产观看浪潮 | 国产区高清 | 日韩国产激情 | 欧美67194| 日本人和亚洲人zjzjhd | 亚洲免费福利 | 国产精品美女高潮无套 | 自拍 亚洲 欧美 | 中文字幕一区二区三区日韩精品 | 韩国av永久免费 | 国产精品永久久久久久久久久 | 奇米网狠狠干 | 岛国伊人 | 一级α片免费看刺激高潮视频 | 午夜啪啪福利视频 | 少妇闺蜜换浪荡h肉辣文 | wwwwww色| 亚洲一区二区三区在线免费观看 | 懂色一区二区三区 | 公侵犯人妻一区二区三区 | 催眠调教后宫乱淫校园 | 在线观看网站av | 国产青青| 97视频免费看 | 国产无遮挡又黄又爽在线观看 | 中文字幕88 | 午夜天堂精品久久久久 | 黄色片hd | 午夜性色福利视频 | 久久久久亚洲av无码专区桃色 | 免费高清毛片 | 欧美精品1区2区3区 精品成人一区 | a级免费观看| 国产在线观看免费视频软件 | 欧洲性猛交 | 美女被草视频在线观看 | www.奇米.com|