Category Archives: 07.Xử lý mảng và Collection

Bài 21-Collections trong Kotlin


Không giống như các ngôn ngữ lập trình khác, Kotlin phân biệt rõ 2 loại Collections(Mutable collections và Immutable collections).

Mô hình lớp kế thừa của các Collection trong Kotlin/java:

Mutable Collections là tập các lớp dùng để lưu trữ danh sách dữ liệu và có thể thay đổi kích thước được

Immutable Collections là tập các lớp dùng để lưu trữ danh sách dữ liệu và không thể thay đổi kích thước được

Cả 2 loại Collections này rất dễ tạo và sử dụng, chỉ khác nhau chút xíu ở mục đích sử dụng của lập trình viên.

Trong giới hạn bài học này Tui chỉ trình bày về MutableListList, các lớp Collection khác các bạn tự tìm hiểu thêm nếu trong dự án có gặp. Tuy nhiên với MutableListList thì theo Tui bạn đã có thể xử lý được hầu hết các trường hợp lưu trữ, tương tác, hiển thị dữ liệu trong phần mềm rồi.

MutableList Là collection có thể thay đổi kích thước dữ liệu: Có thể thêm, sửa, xóa…

List Là collection chỉ có nhiệm vụ readOnly, dùng để hiển thị thông tin. Và dĩ nhiên nó sẽ tối ưu bộ nhớ hơn so với MutableList. Do đó nếu như bạn chỉ muốn hiển thị thông tin thì nên dùng List.

Các collection trong Kotlin không có các Constructor khởi tạo riêng, mà nó thông qua các hàm mutableListOf(), listOf() để khởi tạo

Ví dụ 1 dưới đây mình họa cách khởi tạo 2 collections:


var ds1:MutableList =mutableListOf()
var ds2:List = listOf()

Ở trên 2 đối tượng ds1 và ds2 được khởi tạo với danh sách rỗng.

Ta có thể khởi tạo với một số dữ liệu ban đầu,

Ví dụ 2


var ds1:MutableList =mutableListOf(5,6,1,0,4)
var ds2:List = listOf(1,2,3,4)

Ở trên ds1 được khởi tạo mặc định với 5 phần tử và ta có thể thay đổi thông tin, kích thước ds1

ds2 được khởi tạo mặc định với 4 phần tử và ta không thể thay đổi thông tin, kích thước ds2. Khi ta dùng List tức là trong đầu ta muốn rằng nó là readOnly, chỉ hiển thị dữ liệu mà thôi.

Dưới đây là một số phương thức thường dùng với MutableList/List:

Tên Thuộc tính/phương thức Mô tả
size Thuộc tính trả về kích thước thực sự của Collection
[i] Indexer cho phép truy suất và thay đổi giá trị tại vị trí i của collection
add() Thêm một phần tử
addAll() Thêm nhiều phần tử
removeAt() Xóa theo vị trí
remove() Xóa theo đối tượng
removeIf{} Xóa theo điều kiện
clear() Xóa toàn bộ danh sách
sort() Sắp xếp tăng dần
sortDescending() Sắp xếp giảm dần
filter {  } Lọc dữ liệu
contains() Kiểm tra Collection có chứa phần tử nào đó hay không

Và còn nhiều các phương thức lợi hại khác, các bạn tự tìm hiểu thêm nhé.

Ví dụ 3 – Thao tác với List:


/**
* Created by cafe on 29/05/2017.
*/
fun main(args: Array) {
var ds:List = listOf(5,6,1,9,-4,7,8,2)
println("Các phần tử trong List cách 1:")
for(i in ds.indices)
print("${ds[i]}\t")
println()
println("Các phần tử trong List cách 2:")
for(i in ds)
print("$i\t")
println()
println("Các phần tử sắp xếp tăng dần:")
var ds2= ds.sorted()
for(i in ds2)
print("$i\t")
println()
println("Các phần tử sắp xếp giảm dần:")
var ds3= ds.sortedDescending()
for(i in ds3)
print("$i\t")
println()
var ds4=ds.filter { x->x%2==0 }
println("Các phần tử chẵn:")
for(i in ds4)
print("$i\t")
println()
println("SUM="+ds.sum())
println("MAX="+ds.max())
println("MIN="+ds.min())
println("AVERAGE="+ds.average())
}

Kết quả khi chạy ta thấy:

Các phần tử trong List cách 1:
5    6    1    9    -4    7    8    2
Các phần tử trong List cách 2:
5    6    1    9    -4    7    8    2
Các phần tử sắp xếp tăng dần:
-4    1    2    5    6    7    8    9
Các phần tử sắp xếp giảm dần:
9    8    7    6    5    2    1    -4
Các phần tử chẵn:
6    -4    8    2
SUM=34
MAX=9
MIN=-4
AVERAGE=4.25

Ta để ý các phương thức của List đa phần không làm thay đổi nội tại List mà nó trả về một List mới.

Ví dụ 4 – Thao tác với MutableList:


/**
* Created by cafe on 29/05/2017.
*/
fun main(args: Array) {
var ds:MutableList = mutableListOf()
ds.add(10)//thêm một phần tử có giá trị 10
ds.add(4)//thêm một phần tử có giá trị 4
ds.add(5)//thêm một phần tử có giá trị 5
ds.add(8)//thêm một phần tử có giá trị 8
ds.addAll(mutableListOf(9,0,7))//thêm một danh sách có 3 phần tử: 9,0,7
println("Các phần tử trong MutableList - theo giá trị:")
for(i in ds)
print("$i\t")
println()
println("Các phần tử trong MutableList - theo vị trí:")
for(i in ds.indices)
print("${ds[i]}\t")
println()
ds[2]=113//đổi giá trị phần tử thứ 2 thành 113
println("Các phần tử trong MutableList sau khi đổi:")
for(i in ds.indices)
print("${ds[i]}\t")
println()
ds.removeAt(3)//xóa phần tử tại vị trí thứ 3
println("Các phần tử trong MutableList sau khi xóa:")
for(i in ds.indices)
print("${ds[i]}\t")
println()
ds.sort()//sắp tăng dần
println("Các phần tử trong MutableList sau sắp tăng dần:")
for(i in ds.indices)
print("${ds[i]}\t")
println()
ds.sortDescending()//sắp giảm dần
println("Các phần tử trong MutableList sau sắp giảm dần:")
for(i in ds.indices)
print("${ds[i]}\t")
println()
println("SUM="+ds.sum())
println("MAX="+ds.max())
println("MIN="+ds.min())
println("AVERAGE="+ds.average())
//lọc các số lẻ
var dsLe=ds.filter { x->x%2==1 }
println("Các phần tử trong MutableList là số lẻ:")
for(i in dsLe.indices)
print("${dsLe[i]}\t")
println()
var dsNT=ds.filter {
x->
var dem=0
for(i in 1..x)
{
if(x%i==0)
dem++
}
dem==2
}
println("Các phần tử trong MutableList là số nguyên tố:")
for(i in dsNT.indices)
print("${dsNT[i]}\t")
println()
}

Kết quả khi chạy ta thấy:

Các phần tử trong MutableList – theo giá trị:
10    4    5    8    9    0    7
Các phần tử trong MutableList – theo vị trí:
10    4    5    8    9    0    7
Các phần tử trong MutableList sau khi đổi:
10    4    113    8    9    0    7
Các phần tử trong MutableList sau khi xóa:
10    4    113    9    0    7
Các phần tử trong MutableList sau sắp tăng dần:
0    4    7    9    10    113
Các phần tử trong MutableList sau sắp giảm dần:
113    10    9    7    4    0
SUM=143
MAX=113
MIN=0
AVERAGE=23.833333333333332
Các phần tử trong MutableList là số lẻ:
113    9    7
Các phần tử trong MutableList là số nguyên tố:
113    7

Ta thấy collection trong Kotlin rất linh động và mạnh mẽ, ta có thể tùy biến trong vấn đề xử lý. Hàm filter như là một cuộc cách mạng trong lọc dữ liệu.

Như vậy tới đây Tui đã hướng dẫn xong cách xử 2 Collection quan trọng trong Kotlin, các bạn chú ý học kỹ và hiểu được nó thông qua các ví dụ ở trên nhé. Cần thành thạo các Collection để có thể áp dụng tốt vào các dự án thực tế của mình.

Các bạn có thể tải source code bài này ở đây: http://www.mediafire.com/file/d1b3imc09aw60et/HocXuLyCollection.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://communityuni.com/)

Bài 20- Xử lý mảng hai chiều trong Kotlin


bài 19 chúng ta đã thao tác được với mảng 1 chiều. Trong bài này Tui sẽ trình bày về cách thức khai báo và sử dụng mảng 2 chiều của Kotlin.

Cú pháp khai báo mảng 2 chiều tổng quát trong Kotlin:

var M:Array<Kiểu_Dữ_Liệu_Mảng> = Array(Số_Dòng,{Kiểu_Dữ_Liệu_Mảng(Số_Cột)})

Ví dụ dưới đây sẽ khai báo một mảng 2 chiều tên là M có 10 dòng và 5 cột, dữ liệu các phần tử trong M có kiểu Int:

var M:Array<IntArray> = Array(10,{IntArray(5)})

Các chỉ số dòng và cột cũng chạy từ 0->n-1

Bạn có thể tưởng tượng cấu trúc dữ liệu của mảng 2 chiều như sau:

Mảng 2 chiều trong Kotlin cũng có một tập các phương thức vô cùng mạnh mẽ.

Để nhập liệu cho các phần tử trong mảng 2 chiều M ta làm như sau:

var rd:Random = Random()
for(i in M.indices)
{
for(j in M[i].indices)
{
M[i][j]=rd.nextInt(100)
}
}

Ta dùng 2 vòng lặp for duyệt theo vị trí (indices). Vòng lặp ngoài là duyệt theo dòng, vòng lặp trong là duyệt theo cột. Mỗi làn duyệt ta có M[i][j] chính là phần tử ở dòng thứ i và cột thứ j. Ta cập nhật dữ liệu cho phần tử này.

Để xuất dữ liệu ra màn hình ta cũng làm tương tự:

for(i in M.indices)
{
for(j in M[i].indices)
{
print(“${M[i][j]}\t”)
}
println()
}

Ví dụ chi tiết một số chức năng xử lý Mảng 2 chiều trong Kotlin:


import java.util.*

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var M:Array = Array(10,{IntArray(5)})
var rd:Random = Random()
for(i in M.indices)
{
for(j in M[i].indices)
{
M[i][j]=rd.nextInt(100)
}
}
println("Mảng 2 chiều sau khi nhập:")
for(i in M.indices)
{
for(j in M[i].indices)
{
print("${M[i][j]}\t")
}
println()
}
println("Mảng 2 chiều sau khi nhập - cách 2:")

for(row in M)
{
for(cell in row)
{
print("$cell \t")
}
println()
}
println("Mảng thứ 1:")
var M1=M[1]
for (i in M1.indices)
print("${M1[i]}\t")
println()
}

Kết quả khi chạy ta thấy:

Mảng 2 chiều sau khi nhập:
51    9    58    96    46
48    76    11    68    44
11    73    77    18    45
22    10    91    22    35
59    66    48    42    59
84    5    58    0    79
50    68    72    29    64
8    66    69    90    93
35    92    5    8    13
18    48    44    82    52
Mảng 2 chiều sau khi nhập – cách 2:
51     9     58     96     46
48     76     11     68     44
11     73     77     18     45
22     10     91     22     35
59     66     48     42     59
84     5     58     0     79
50     68     72     29     64
8     66     69     90     93
35     92     5     8     13
18     48     44     82     52
Mảng thứ 1:
48    76    11    68    44

Như vậy tới đây Tui đã hướng dẫn xong cách khai báo, nhập, xuất mảng 2 chiều trong Kotlin, các bạn chú ý học kỹ và hiểu được nó thông qua các ví dụ ở trên nhé. Các bạn Cần kiểm tra thêm nhiều phương thức khác trong mảng 2 chiều để có thể áp dụng tốt vào các dự án thực tế của mình.

Các bạn có thể tải source code bài này ở đây:http://www.mediafire.com/file/sxi7swegsgcsz17/HocXuLyMang_2d.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://communityuni.com/)

Bài 19- Xử lý mảng một chiều trong Kotlin


Với Kotlin thì Mảng là một kiểu dữ liệu rất mạnh mẽ, nó khắc phục được rất nhiều nhược điểm so với các ngôn ngữ lập trình khác như C++, C#, Java…

bài số 6 Tui đã nói sơ qua một số kiểu dữ liệu là mảng được built-in sẵn trong Kotlin. Để giúp các bạn dễ dàng hiểu được cách khai báo cũng như sử dụng mảng một chiều trong Kotlin thì Tui sẽ dùng IntArray để minh họa trong các ví dụ dưới đây, các kiểu mảng khác các bạn có thể tự suy luận được.

Để khai báo và cấp phát mảng ta làm như sau:

var M:IntArray= IntArray(n)

Với n là số phần tử lưu trữ tối đa của mảng.

M là một mảng lưu trữ tập các kiểu dữ liệu Int (lưu trữ tối đa n phần tử). Ta cũng có thể nói M là một đối tượng có kiểu IntArray. Tương tự như các ngôn ngữ lập trình khác, Mảng cũng lưu chỉ số từ 0, cho phép truy suất các phần tử thông qua chỉ số:

Nhưng các bạn cần chú ý là việc truy suất phần tử chỉ là một chức năng vô cùng nhỏ trong mảng của Kotlin, vì với Mảng trong Kotlin nó rất phong phú các phương thức, nó là một đối tượng được xây dựng với vô vàn phương thức xử lý rất hiệu quả: Tìm min, max, trung bình, tổng, tìm kiếm, sắp xếp…

Tui liệt kê một số thuộc tính và phương thức thường dùng của Mảng (dĩ nhiên còn rất nhiều phương thức khác, khi nào gặp thì các bạn nghiên cứu thêm):

Tên Thuộc tính/phương thức Mô tả
size Thuộc tính trả về kích thước thực sự của mảng
[i] Indexer cho phép truy suất và thay đổi giá trị tại vị trí i của mảng
count/count{} đếm/ đếm có điều kiện
min() hàm trả về số nhỏ nhất trong mảng
max() hàm trả về số lớn nhất trong mảng
sum() hàm trả về tổng mảng
average() hàm trả về trung bình mảng
sort() sắp xếp mảng tăng dần
sortDescending() sắp xếp mảng giảm dần
filter{} Tìm kiếm/lọc danh sách trong mảng
reverse() Đảo mảng
contains() Kiểm tra Mảng có chứa phần tử nào đó hay không

Ví dụ khai báo mảng M có khả năng chứa tối đa 10 phần tử:

var M:IntArray= IntArray(10)

Nhập giá trị cho từng phần tử trong mảng M:

M[0]=100

M[1]=20

M[9]=-5

Vì mảng M có khả năng chứa 10 phần tử nên các Indexer sẽ chạy từ 0 –> 9

Để lấy giá trị tại một vị trí bất kỳ:

var x:Int=M[2]

Để duyệt các phần tử trong mảng ta  có thể duyệt theo vị trí như sau:

for (i in M.indices)
print(“${M[i]}\t”)

hoặc duyệt giá trị theo cách:

for (i in M)
print(“$i\t”)

Các hàm khác trong mảng cũng dễ dàng thực hiện.

Ví dụ chi tiết tạo mảng M có 10 phần tử với các giá trị ngẫu nhiên:


import java.util.*

/**
* Created by cafe on 28/05/2017.
*/
fun main(args: Array) {
var M:IntArray= IntArray(10)

var rd=Random()
for(i in M.indices)
M[i]=rd.nextInt(100)//nhập giá trị là các số ngẫu nhiên [0..99]
println("Mảng sau khi nhập - duyệt theo giá trị:")
for (i in M)
print("$i\t")
println()
println("Mảng sau khi nhập - duyệt theo vị trí:")
for (i in M.indices)
print("${M[i]}\t")
println()
//số lớn nhất
println("MAX=${M.max()}")
//số nhỏ nhất
println("MIN=${M.min()}")
//tổng mảng
println("SUM=${M.sum()}")
//trung bình mảng
println("AVERAGE=${M.average()}")
//đếm số chẵn
println("Số chẵn=${M.count { x->x%2==0 }}")
//đếm số lẻ
println("Số lẻ=${M.count { x->x%2==1 }}")
//sắp xếp tăng dần
M.sort()
println("Tăng dần:")
for (i in M)
print("$i\t")
println()
//sắp xếp giảm dần
M.sortDescending()
println("Giảm dần:")
for (i in M)
print("$i\t")
println()
//lọc các số chẵn trong mảng
var dsChan= M.filter { x->x%2==0 }
println("Các số chẵn:")
for (i in dsChan)
print("$i\t")
println()
//lọc các số lẻ trong mảng
var dsLe= M.filter { x->x%2==1 }
println("Các số Lẻ:")
for (i in dsLe)
print("$i\t")
println()
var k=50
//lọc các số >50 trong mảng
var dsTim=M.filter { x->x>k }
println("Các số > $k:")
for (i in dsTim)
print("$i\t")
println()
}

Kết quả khi chạy ta thấy:

Mảng sau khi nhập – duyệt theo giá trị:
47    50    51    71    63    96    65    91    1    90
Mảng sau khi nhập – duyệt theo vị trí:
47    50    51    71    63    96    65    91    1    90
MAX=96
MIN=1
SUM=625
AVERAGE=62.5
Số chẵn=3
Số lẻ=7
Tăng dần:
1    47    50    51    63    65    71    90    91    96
Giảm dần:
96    91    90    71    65    63    51    50    47    1
Các số chẵn:
96    90    50
Các số Lẻ:
91    71    65    63    51    47    1
Các số > 50:
96    91    90    71    65    63    51

Như vậy tới đây Tui đã hướng dẫn xong cách xử mảng 1 chiều trong Kotlin, các bạn chú ý học kỹ và hiểu được nó thông qua các ví dụ ở trên nhé. Cần thành thạo các thư viện để có thể áp dụng tốt vào các dự án thực tế của mình.

Bài sau Tui sẽ trình bày về mảng 2 chiều trong Kotlin

Các bạn có thể tải source code bài này ở đây: http://www.mediafire.com/file/yha9wwfu1879ac4/HocXuLyMang_1d.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://ssoftinc.com/)

%d bloggers like this: