Thursday, April 21, 2016

[Đồ thị] Lý thuyết đồ thị - Đường đi, Chu trình, Đồ thị liên thông

Đồ thị: là một cấu trúc dữ liệu rời rạc bao gồm các đỉnh và các cạnh nối các cặp đỉnh này. Chúng ta phân biệt đồ thị thông qua kiểu và số lượng cạnh nối giữa các cặp đỉnh của đồ thị.
Dưới đây là một ví dụ về mạng máy tính bao gồm: mỗi máy tính là một đỉnh, mỗi kênh điện thoại kết nối là cạnh của đồ thị
Đồ thị: Mạng máy tính

Trong mạng máy tính trên, mỗi máy tính là một đỉnh của đồ thị, các kênh điện thoại là cạnh của đồ thị, không có hai cặp cạnh nào nối cùng một cặp đỉnh. Ta gọi đây là đơn đồ thị vô hướng.
Đơn đồ thị vô hướng: Đơn đồ thị vô hướng G = <V,E> bao gồm V là tập các đỉnh, E là tập các cặp có thứ tự gồm hai phần tử khác nhau của V gọi là các cạnh.
Trong trường hợp giữa máy tính nào đó thường xuyên phải truyền tải thông tin nên người ta xây dựng thêm một kênh điện thoại nữa để tăng khả năng truyền tải thông tin, khi đó hai máy tính sẽ có nhiều hơn một kênh điện thoại kết nối. Ta gọi đây là đa đồ thị vô hướng.
Mạng máy tính đa kênh thoại

Đa đồ thị vô hướng: G = <V, E> bao gồm V là tập các đỉnh, E là họ các cặp không có thứ tự gồm hai phần tử khác nhau của V gọi là tập các cạnh. e1, e2 được gọi là cạnh lặp nếu chúng cùng tương ứng với một cặp đỉnh.
Mạng máy tính đa kênh thoại có khuyên

Giả đồ thị vô hướng: G = <V, E> bao gồm V là tập đỉnh, E là họ các cặp không có thứ tự gồm hai phần tử (hai phần tử không nhất thiết phải khác nhau) trong V được gọi là các cạnh. Cạnh e được gọi là khuyên nếu có dạng e =(u, u), trong đó u là đỉnh nào đó thuộc V.

Trong nhiều mạng, các kênh kết nối giữa hai máy tính chỉ có thể truyền tải thông tin theo một chiều.Chẳng hạn máy tính đặt tại Hà Nội có thể truy cập dữ liệu của máy tính đặt tại Hải Phòng, nhưng máy tính ở Hải Phòng không thể truy cập dữ liệu của máy tính ở Hà Nội. Để mô tả mạng máy tính này chúng ta dùng khái niệm đồ thị có hướng.
Mạng máy tính có hướng

Đơn đồ thị có hướng G = <V, E> bao gồm V là tập các đỉnh, E là tập các cặp có thứ tự gồm hai phần tử của V gọi là các cung.
Trong trường hợp có nhiều hơn một kênh có hướng kết nối giữa hai đỉnh của đồ thị, để mô tả mạng máy tính này ta dùng khái niệm đa đồ thị có hướng.
Mạng máy tính đa kênh một chiều 

Đa đồ thị có hướng G = <V, E> bao gồm V là tập đỉnh, E là cặp có thứ tự gồm hai phần tử của V được gọi là các cung. Hai cung e1, e2 tương ứng với cùng một cặp đỉnh được gọi là cung lặp.
Loại đồ thị Cạnh Có cạnh bội Có khuyên
Đơn đồ thị vô hướng Vô hướng Không Không
Đa đồ thị vô hướng Vô hướng Không
Giả đồ thị vô hướng Vô hướng
Đồ thị có hướng Có hướng Không
Đa đồ thị có hướng Có hướng
*Hai đỉnh u và v của đồ thị vô hướng G =<V, E> được gọi là kề nhau nếu (u,v) là cạnh thuộc đồ thị G. Nếu e =(u, v) là cạnh của đồ thị G thì ta nói cạnh này liên thuộc với hai đỉnh u và v, hoặc ta nói cạnh e nối đỉnh u với đỉnh v, đồng thời các đỉnh u và v sẽ được gọi là đỉnh đầu của cạnh (u,v).
*Ta gọi bậc của đỉnh v trong đồ thị vô hướng là số cạnh liên thuộc với nó và ký hiệu là deg(v).
deg(a) = 2, deg(b) =deg(c) = deg(f) = 4, deg(e) = 3, deg(d) = 1, deg(g)=0.
Đồ thị có hướng G
Nếu e=(u,v) là cung của đồ thị có hướng G thì ta nói hai đỉnh u và v là kề nhau, và nói cung (u, v) nối đỉnh u với đỉnh v. Đỉnh u sẽ được gọi là đỉnh đầu v là đỉnh cuối của cung (u,v).
Ta gọi bán bậc ra (bán bậc vào) của đỉnh v trong đồ thị có hướng là số cung của đồ thị đi ra khỏi nó (đi vào nó) và ký hiệu là deg+(v) và deg-(v).
deg-(a) = 1, deg-(b) = 2, deg-(c) = 2, deg-(d) = 2, deg-(e) = 2. deg+(a) = 3, deg+(b) = 1, deg+(c) = 1, deg+(d) = 2, deg+(e) = 2.
Đường đi: Đường đi độ dài n từ đỉnh u đến đỉnh v trên đồ thị vô hướng G=<V,E> là dãy: x0, x1,..., xn-1, xn trong đó n là số nguyên dương, x0=u, xn=v, (xi, xi+1)∈E, i =0, 1, 2,..., n-1.
Đường đi như trên còn có thể biểu diễn thành dãy các cạnh:
(x0, x1), (x1,x2),..., (xn-1, xn).
Đỉnh u là đỉnh đầu, đỉnh v là đỉnh cuối của đường đi. Đường đi có đỉnh đầu trùng với đỉnh cuối (u=v) được gọi là chu trình. Đường đi hay chu trình được gọi là đơn nếu như không có cạnh nào lặp lại.
Đồ thị vô hướng được gọi là liên thông nếu luôn tìm được đường đi giữa hai đỉnh bất kỳ của nó.

Wednesday, February 17, 2016

[Android] Swipe RecyleView cho Android

Sau một thời gian sử dụng sử dụng Gmail và Outlook mình bắt đầu tìm hiểu và tìm kiếm một thư viện hỗ trợ để có được những hiệu ứng tương tự.

Sau khi Google mình tìm thấy thư viện AndroidSwipeLayout có hỗ trợ các hiệu ứng khá đẹp. Thư viện khi kết hợp với RecycleView sẽ tạo ra nhiều option cho người dùng chọn khi swipe trái/phải màn hình.
Bài viết này mình sẽ hướng dẫn các bạn thêm thư viện AndroidSwipeLayout kết hợp với RecyclerView vào project.
Các bước thực hiện như sau:
Bước 1: Add thư viện
Mở file gradle và thêm dòng sau.
compile 'com.daimajia.swipelayout:library:1.2.0@aar'
Bước 2: Định nghĩa item của listview
Trong phần res/layout, thêm file swipe_row_item.xml dùng để định nghĩa một thành phần của Listview.
<?xml version="1.0" encoding="utf-8" ?>
<com.daimajia.swipe.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:swipe="http://schemas.android.com/apk/res-auto"
    android:id="@+id/swipe"
    android:layout_width="match_parent"
    android:layout_height="73dp"
    swipe:leftEdgeSwipeOffset="0dp"
    swipe:rightEdgeSwipeOffset="0dp">

    <!--Bottom View For Right to Left-->

    <LinearLayout
        android:id="@+id/bottom_wrapper"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:weightSum="3">

        <TextView
            android:id="@+id/tvEdit"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#0076a5"
            android:gravity="center"
            android:text="Edit"
            android:textColor="#fff" />

        <TextView
            android:id="@+id/tvShare"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#003c54"
            android:gravity="center"
            android:text="Share"
            android:textColor="#fff" />

        <TextView
            android:id="@+id/tvDelete"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#0076a5"
            android:gravity="center"
            android:text="Delete"
            android:textColor="#fff" />
    </LinearLayout>


    <!-- Another Bottom View For Left to Right -->

    <LinearLayout
        android:id="@+id/bottom_wrapper1"
        android:layout_width="80dp"
        android:layout_height="match_parent"
        android:weightSum="1">

        <ImageButton
            android:id="@+id/btnLocation"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@null"
            android:gravity="center"
            android:src="@drawable/location_icon" />
    </LinearLayout>

    <!-- Top View,  Row itemView of RecyclerView -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="73dp"
        android:background="?android:selectableItemBackground"
        android:orientation="horizontal">
        <RelativeLayout
            android:layout_width="85dp"
            android:layout_height="match_parent"
            android:paddingLeft="18dp"
            android:paddingRight="18dp"
            android:paddingTop="8dp"
            android:paddingBottom="8dp">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/contact_default"/>
        </RelativeLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:paddingRight="18dp"
            android:paddingTop="15dp"
            android:paddingBottom="15dp">
            >
            <!--contact name layout-->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <TextView
                    android:id="@+id/tvName"
                    android:layout_width="200dp"
                    android:layout_height="20dp"
                    android:text="Name"
                    android:textColor="@android:color/black"
                    android:textSize="16sp" />
                <TextView
                    android:id="@+id/tvDeliveryStatus"
                    android:layout_width="match_parent"
                    android:layout_height="20dp"
                    android:gravity="right"
                    android:textAlignment="gravity"
                    android:text="Sent"/>
            </LinearLayout>
            <!--message content-->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <TextView
                    android:id="@+id/tvEmailId"
                    android:layout_width="200dp"
                    android:layout_height="20dp"
                    android:layout_below="@+id/tvName"
                    android:text="Email Id"
                    android:textColor="@android:color/black"
                    android:textSize="12sp" />
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:adjustViewBounds="true"
                    android:scaleType="fitEnd"
                    android:src="@drawable/facebook_icon"/>
            </LinearLayout>
        </LinearLayout>


    </LinearLayout>

</com.daimajia.swipe.SwipeLayout>
Bước 3: Tạo lớp Student.
package com.blogspot.simplecodecjava.swiperecycleview;
import java.io.Serializable;
public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private String emailId;
    public Student() {
    }
    public Student(String name, String emailId) {
        this.name = name;
        this.emailId = emailId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmailId() {
        return emailId;
    }
    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }
}
Bước 4: Tạo lớp SwipeRecyclerViewAdapter kế thừa từ RecyclerSwipeAdapter.
package com.blogspot.simplecodecjava.swiperecycleview;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.daimajia.swipe.SwipeLayout;
import com.daimajia.swipe.adapters.RecyclerSwipeAdapter;
import com.slab.schedulerchat.R;

import java.util.ArrayList;

public class SwipeRecyclerViewAdapter extends RecyclerSwipeAdapter<SwipeRecyclerViewAdapter.SimpleViewHolder> {


    private Context mContext;
    private ArrayList<Student> studentList;

    public SwipeRecyclerViewAdapter(Context context, ArrayList<Student> objects) {
        this.mContext = context;
        this.studentList = objects;
    }

    @Override
    public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.swipe_row_item, parent, false);
        return new SimpleViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final SimpleViewHolder viewHolder, final int position) {
        final Student item = studentList.get(position);

        viewHolder.tvName.setText((item.getName()) + "  -  Row Position " + position);
        viewHolder.tvEmailId.setText(item.getEmailId());


        viewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.PullOut);

        // Drag From Left
        viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Left, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper1));

        // Drag From Right
        viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Right, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper));


        // Handling different events when swiping
        viewHolder.swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {
            @Override
            public void onClose(SwipeLayout layout) {
                //when the SurfaceView totally cover the BottomView.
            }

            @Override
            public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {
                //you are swiping.
            }

            @Override
            public void onStartOpen(SwipeLayout layout) {

            }

            @Override
            public void onOpen(SwipeLayout layout) {
                //when the BottomView totally show.
            }

            @Override
            public void onStartClose(SwipeLayout layout) {

            }

            @Override
            public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {
                //when user's hand released.
            }
        });

        /*viewHolder.swipeLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                if ((((SwipeLayout) v).getOpenStatus() == SwipeLayout.Status.Close)) {
                    //Start your activity

                    Toast.makeText(mContext, " onClick : " + item.getName() + " \n" + item.getEmailId(), Toast.LENGTH_SHORT).show();
                }

            }
        });*/

        viewHolder.swipeLayout.getSurfaceView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, " onClick : " + item.getName() + " \n" + item.getEmailId(), Toast.LENGTH_SHORT).show();
            }
        });


        viewHolder.btnLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Toast.makeText(v.getContext(), "Clicked on Map " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });


        viewHolder.tvShare.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Toast.makeText(view.getContext(), "Clicked on Share " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });

        viewHolder.tvEdit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Toast.makeText(view.getContext(), "Clicked on Edit  " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });


        viewHolder.tvDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mItemManger.removeShownLayouts(viewHolder.swipeLayout);
                studentList.remove(position);
                notifyItemRemoved(position);
                notifyItemRangeChanged(position, studentList.size());
                mItemManger.closeAllItems();
                Toast.makeText(view.getContext(), "Deleted " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });


        // mItemManger is member in RecyclerSwipeAdapter Class
        mItemManger.bindView(viewHolder.itemView, position);

    }

    @Override
    public int getItemCount() {
        return studentList.size();
    }

    @Override
    public int getSwipeLayoutResourceId(int position) {
        return R.id.swipe;
    }


    //  ViewHolder Class

    public static class SimpleViewHolder extends RecyclerView.ViewHolder {
        SwipeLayout swipeLayout;
        TextView tvName;
        TextView tvEmailId;
        TextView tvDelete;
        TextView tvEdit;
        TextView tvShare;
        ImageButton btnLocation;

        public SimpleViewHolder(View itemView) {
            super(itemView);
            swipeLayout = (SwipeLayout) itemView.findViewById(R.id.swipe);
            tvName = (TextView) itemView.findViewById(R.id.tvName);
            tvEmailId = (TextView) itemView.findViewById(R.id.tvEmailId);
            tvDelete = (TextView) itemView.findViewById(R.id.tvDelete);
            tvEdit = (TextView) itemView.findViewById(R.id.tvEdit);
            tvShare = (TextView) itemView.findViewById(R.id.tvShare);
            btnLocation = (ImageButton) itemView.findViewById(R.id.btnLocation);


        }
    }
}
Bước 5: Khai báo MainAtivity.
package com.blogspot.simplecodecjava.swiperecycleview;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private ArrayList<Student> mDataSet;
    private String TAG = MainActivity.class.getName();
    private Toolbar toolbar;
    private TextView tvEmptyView;
    private RecyclerView mRecyclerView;
    private volatile static MainActivity mInstance;
    public static MainActivity getInstance(Context context){
        if(mInstance == null){
            synchronized (MainActivity.class){
                if(mInstance == null){
                    mInstance = new MainActivity();
                }
            }
        }
        return mInstance;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        tvEmptyView = (TextView) findViewById(R.id.empty_view);
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mDataSet = new ArrayList<Student>();
        if (toolbar != null) {
            setSupportActionBar(toolbar);
            getSupportActionBar().setTitle("Android Students");

        }
        loadData();
        if (mDataSet.isEmpty()) {
            mRecyclerView.setVisibility(View.GONE);
            tvEmptyView.setVisibility(View.VISIBLE);

        } else {
            mRecyclerView.setVisibility(View.VISIBLE);
            tvEmptyView.setVisibility(View.GONE);
        }
        SwipeRecyclerViewAdapter mAdapter = new SwipeRecyclerViewAdapter(this, mDataSet);
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                Log.e("RecyclerView", "onScrollStateChanged");
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });
    }
    public void loadData() {

        for (int i = 0; i <= 20; i++) {
            mDataSet.add(new Student("Student " + i, "androidstudent" + i + "@gmail.com"));
        }
    }
}
Bước 6: Khai báo activity_main layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FF4081"
        android:elevation="8dp"
        android:minHeight="?attr/actionBarSize">

    </android.support.v7.widget.Toolbar>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_margin="5dp"
        android:layout_weight="1"
        android:scrollbars="vertical" />
    <TextView
        android:id="@+id/empty_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="No Records"
        android:visibility="gone" />


</LinearLayout>
Bạn có thể tải project mẫu tại đây.
Nguồn: blogger.com

Monday, February 15, 2016

[Android] Thư viện TimePicker & DatePicker đẹp cho android.

Qua một thời gian sử dụng Google calendar mình thấy cách chọn thời gian để đặt sự kiện, ghi nhớ rất dễ hiểu và trực quan. Bạn hãy xem cách Time/Date Picker của Google hoạt động trên Google calendar.
Qua một thời gian search trên Google để tìm thư viện mã nguồn mở về cách lựa chọn thời gian giống như trên mình có tìm thấy android-betterpickers.
Dưới đây là hình ảnh về Time/Date Picker thư viện hỗ trợ.

Sau đây mình sẽ hướng dẫn các bạn thêm thư viện vào trong project bằng Android studio.
Bước 1: Add thư viện vào trong file gradle.
Mở file gradle và thêm dòng sau.
compile 'com.code-troopers.betterpickers:library:2.5.1'

*Trong trường hợp add thư viện vào bạn nhận được thông báo
Error:A problem occurred configuring project ':app'.
> Could not download library.aar (com.code-troopers.betterpickers:library:2.5.1)
   > Could not get resource 'https://jcenter.bintray.com/com/code-troopers/betterpickers/library/2.5.1/library-2.5.1.aar'.
      > Could not GET 'https://jcenter.bintray.com/com/code-troopers/betterpickers/library/2.5.1/library-2.5.1.aar'.
         > peer not authenticated

Lỗi trên có thể được khắc phục bằng cách thực hiện các bước sau:
  1. Download library-2.5.1.aar bằng trình cách paste vào trình duyệt địa chỉ https://jcenter.bintray.com/com/code-troopers/betterpickers/library/2.5.1/library-2.5.1.aar
  2. Copy file library-2.5.1.aar vào thư mục libs
  3. Thêm
    allprojects {
       repositories {
          jcenter()
          flatDir {
            dirs 'libs'
          }
       }
    }
    
    dependencies {
        compile(name:'library-2.5.1', ext:'aar')
    }
    

    vào file build gradle.
Bước 2: Bắt action và hiển thị Time/Date Picker vào main code.
Dưới đây là các ví dụ:
1. Calendar Date Picker.
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        CalendarDatePickerDialogFragment cdp = new CalendarDatePickerDialogFragment()
                .setOnDateSetListener(SampleCalendarDateBasicUsage.this)
                .setFirstDayOfWeek(Calendar.SUNDAY)
                .setPreselectedDate(towDaysAgo.getYear(), towDaysAgo.getMonthOfYear() - 1, towDaysAgo.getDayOfMonth())
                .setDateRange(minDate, null)
                .setThemeDark(true);
        cdp.show(getSupportFragmentManager(), FRAG_TAG_DATE_PICKER);
    }
});

2. Redial Time Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        RadialTimePickerDialogFragment rtpd = new RadialTimePickerDialogFragment()
                .setOnTimeSetListener(SampleRadialTimeBasicUsage.this)
                .setStartTime(10, 10)
                .setThemeDark(true);
        rtpd.show(getSupportFragmentManager(), FRAG_TAG_TIME_PICKER);
    }
});
3. Recurrence Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        FragmentManager fm = getSupportFragmentManager();
        Bundle bundle = new Bundle();
        Time time = new Time();
        time.setToNow();
        bundle.putLong(RecurrencePickerDialogFragment.BUNDLE_START_TIME_MILLIS, time.toMillis(false));
        bundle.putString(RecurrencePickerDialogFragment.BUNDLE_TIME_ZONE, time.timezone);
        bundle.putString(RecurrencePickerDialogFragment.BUNDLE_RRULE, mRrule);
        bundle.putBoolean(RecurrencePickerDialogFragment.BUNDLE_HIDE_SWITCH_BUTTON, true);

        RecurrencePickerDialogFragment rpd = new RecurrencePickerDialogFragment();
        rpd.setArguments(bundle);
        rpd.setOnRecurrenceSetListener(SampleRecurrenceBasicUsage.this);
        rpd.show(fm, FRAG_TAG_RECUR_PICKER);
    }
});
4. Timezone Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        FragmentManager fm = getSupportFragmentManager();
        Bundle bundle = new Bundle();
        Time time = new Time();
        time.setToNow();
        bundle.putLong(TimeZonePickerDialogFragment.BUNDLE_START_TIME_MILLIS, time.toMillis(false));
        bundle.putString(TimeZonePickerDialogFragment.BUNDLE_TIME_ZONE, time.timezone);
        bundle.putString(RecurrencePickerDialogFragment.BUNDLE_RRULE, mRrule);

        TimeZonePickerDialogFragment tzpd = new TimeZonePickerDialogFragment();
        tzpd.setArguments(bundle);
        tzpd.setOnTimeZoneSetListener(SampleTimeZoneBasicUsage.this);
        tzpd.show(fm, FRAG_TAG_TIME_ZONE_PICKER);
    }
});
5. Date Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        DatePickerBuilder dpb = new DatePickerBuilder()
                .setFragmentManager(getSupportFragmentManager())
                .setStyleResId(R.style.BetterPickersDialogFragment)
                .setYearOptional(true);
        dpb.show();
    }
});
6. Expiration Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ExpirationPickerBuilder epb = new ExpirationPickerBuilder()
                  .setFragmentManager(getSupportFragmentManager())
                  .setStyleResId(R.style.BetterPickersDialogFragment) 
                  .setMinYear(2000);
        epb.show();
    }
});
7. HMS Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        HmsPickerBuilder hpb = new HmsPickerBuilder()
                .setFragmentManager(getSupportFragmentManager())
                .setStyleResId(R.style.BetterPickersDialogFragment);
        hpb.show();
    }
});
8. Number Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        NumberPickerBuilder npb = new NumberPickerBuilder()
                .setFragmentManager(getSupportFragmentManager())
                .setStyleResId(R.style.BetterPickersDialogFragment)
                .setLabelText("LBS.");
        npb.show();
}
});
9. Time Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        TimePickerBuilder tpb = new TimePickerBuilder()
                .setFragmentManager(getSupportFragmentManager())
                .setStyleResId(R.style.BetterPickersDialogFragment);
        tpb.show();
    }
});
Theming.
Đồng thời bạn có thể định nghĩa theme theo phong cách của riêng bạn.
    bpDialogBackground       :: drawable của DialogFragment background.
    bpTextColor              :: màu của text trong DialogFragment.
    bpDeleteIcon             :: drawable của delete button.
    bpCheckIcon              :: drawable của check button trong DateDialogPicker.
    bpKeyBackground          :: drawable của keyboard buttons.
    bpButtonBackground       :: drawable cho các nút Set, Cancel, and Delete buttons.
    bpDividerColor           :: màu của DialogFragment dividers.
    bpKeyboardIndicatorColor :: màu của ViewPagerIndicator trong DateDialogPicker.
  1. Tạo theme cá nhân trong file styles.xml
    <style name="MyCustomBetterPickerTheme">
        <item name="bpDialogBackground">@drawable/custom_dialog_background</item>
        <item name="bpTextColor">@color/custom_text_color</item>
        <item name="bpDeleteIcon">@drawable/ic_backspace_custom</item>
        <item name="bpCheckIcon">@drawable/ic_check_custom</item>
        <item name="bpKeyBackground">@drawable/key_background_custom</item>
        <item name="bpButtonBackground">@drawable/button_background_custom</item>
        <item name="bpDividerColor">@color/custom_divider_color</item>
        <item name="bpKeyboardIndicatorColor">@color/custom_keyboard_indicator_color</item>
    </style>
    
  2. Khởi tạo DialogFragment có sử dụng theme trên.
    DatePickerBuilder dpb = new DatePickerBuilder()
        .setFragmentManager(getSupportFragmentManager())
        .setStyleResId(R.style.MyCustomBetterPickerTheme);
    dpb.show();
    
Source code của chương trình được tải về tại đây.
Theo gitHub.com

Friday, January 15, 2016

[Java] Copy dữ liệu sang file khác trong Java

Bài viết sẽ trình bày cách copy dữ liệu từ một file sang một file khác trong Java. Theo thứ tự để copy dữ liệu sang file khác, ta cần phải đọc dữ liệu (sử dụng FileInputStream) và viết dữ liệu sang file khác (sử dụng FileOutputStream).
Chương trình sau sẽ copy dữ liệu từ file "MyInputFile.txt" sang file "MyOutputFile.txt". Nếu file "MyOutputFile.txt" chưa tồn tại thì chương trình sẽ tạo file và copy dữ liệu sang file đó.
package simplecodecjava.blogspot.com;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyExample {
 public static void main(String[] args) {
  FileInputStream instream = null;
  FileOutputStream outstream = null;

  try {
   File infile = new File("src/simplecodecjava/blogspot/com/MyInputFile.txt");
   File outfile = new File("src/simplecodecjava/blogspot/com/MyOutputFile.txt");

   instream = new FileInputStream(infile);
   outstream = new FileOutputStream(outfile);

   byte[] buffer = new byte[1024];

   int length;
   /*
    * copy dữ liệu từ file đầu vào sang file đầu ra
    *  sử dụng phương thức read và write trong java.
    */
   while ((length = instream.read(buffer)) > 0) {
    outstream.write(buffer, 0, length);
   }
   /*Đóng luồng input/output*/
   instream.close();
   outstream.close();
   System.out.println("Copy thành công!");
  } catch (IOException ioe) {
   ioe.printStackTrace();
  }
 }
}
Output
Copy thành công!
Chương trình trên sử dụng phương thức read để đọc dữ liệu.
public int read(byte[] b) throws IOException
Khi gọi phương thức trên chương trình sẽ đọc vào mảng buffer 1024 (kích thước của mảng đệm buffer) byte từ luồng dữ liệu đầu vào instream . Phương thức này sẽ trả về số tổng số file được đọc vào mảng buffer. Nếu file không chứa dữ hiệu hoặc chương trình đã đọc đến đoạn kết thúc của file phương thức read sẽ trả về -1.

Chương trình trên sử dụng phương thức write để ghi dữ liệu.
public void write(byte[] b,int off, int length) throws IOException
Phương thức trên sẽ viết length byte từ mảng b bắt đầu từ vị trí off ra file đầu ra.

Saturday, January 9, 2016

[Java] Lấy IP trong Java

Bài viết sẽ hướng dẫn bạn lấy địa chỉ IP từ hệ thống. Các bước để lấy địa chỉ IP như sau:
1. Lấy địa chỉ local host bằng phương thức getLocalHost() của class InetAddress.
2. Lấy địa chỉ IP bằng phương thức getHostAddress().
Chương trình cài đặt.
package simplecodecjava.blogspot.com;

import java.net.InetAddress;

public class GetIPAddress {
 public static void main(String[]args) throws Exception{
  /*phhương thức static InetAddress getLocalHost() ném ra UnknownHostException,
  Phương thức này trả về địa chỉ của local host.*/
  InetAddress myIP = InetAddress.getLocalHost();
  System.out.print("Địa chỉ IP của máy tính là: ");
  System.out.print(myIP.getHostAddress());
  
 }
}

Output:
Địa chỉ IP của máy tính là: 107.113.187.26

Thursday, January 7, 2016

[Java] Chuyển từ hệ thập phân sang hệ nhị phân.

Có 3 cách để chuyển một số từ hệ thập phân sang hệ nhị phân.
  1. Sử dụng phương thức toBinaryString() trong class Integer của Java.
  2. Sử dụng phương thức chuyển đổi bằng logic mà không sử dụng phương thức có sẵn của Java.
  3. Sử dụng Stack.
1. Sử dụng phương thức toBinaryString().
package simplecodecjava.blogspot.com;

public class DecimalToBinaryExample {
 public static void main(String[]args){
  int decimalNumber = 123456789;
  System.out.print("Hệ nhị phân của " + decimalNumber +" là :");
  System.out.print(Integer.toBinaryString(decimalNumber));
 }
}
Output:
Hệ nhị phân của 123456789là :111010110111100110100010101
2. Sử dụng chuyển đổi bằng logic.
package simplecodecjava.blogspot.com;

public class DecimalToBinaryExample {
 
 public void convertBinary(int num){
      int binary[] = new int[40];
      int index = 0;
      while(num > 0){
        binary[index++] = num%2;
        num = num/2;
      }
      for(int i = index-1;i >= 0;i--){
        System.out.print(binary[i]);
      }
   }
  
 public static void main(String[]args){
  int decimalNumber = 123456789;
  System.out.print("Hệ nhị phân của " + decimalNumber +" là :");
  new DecimalToBinaryExample().convertBinary(decimalNumber);
 }
}
Output:
Hệ nhị phân của 123456789 là :111010110111100110100010101
3. Sử dụng Stack.
package simplecodecjava.blogspot.com;

import java.util.Stack;

public class DecimalToBinaryExample {
 
 public void convertBinary(int num){
  Stack<Integer> stack = new Stack<Integer>();
     while(num != 0){
      //thực hiện phép chia lấy phần dư cho 2.
      int d = num%2;
      // thêm vào stack.
      stack.push(d);
      num/=2;
     }
     while(!(stack.isEmpty())){
      System.out.print(stack.pop());
     }
     
   }
  
 public static void main(String[]args){
  int decimalNumber = 123456789;
  System.out.print("Hệ nhị phân của " + decimalNumber +" là :");
  new DecimalToBinaryExample().convertBinary(decimalNumber);
 }
}
Output:
Hệ nhị phân của 123456789 là :111010110111100110100010101

Wednesday, January 6, 2016

[Java] Sự khác nhau giữa HashMap và Hashtable

Sự khác nhau giữa HashMap HashTable ? Đây là câu hỏi thường được đưa ra trong các cuộc phỏng vấn chuyên gia Java/J2EE.
HashMapHashTable đều được implements từ java.util.Map interface. Tuy nhiên có một vài sự khác biệt giữa chúng trong cách thức hoạt động và sử dụng.
HashMap vs HashTable.
1. Khả năng đồng bộ.
- HashMap là lớp không đồng bộ (non-synchronized). Điều đó có nghĩa là HashMap có thể cho phép có nhiều hơn một thread cùng truy cập và sử lý dữ liệu và nó chứa đựng một cách đồng thời.
 void clear()
 Object clone()
 boolean containsKey(Object key)
 boolean containsValue(Object value)
 Set<Entry<K, V>> entrySet()
 V get(Object key)
 boolean isEmpty()
 Set<k> keySet()
 V put(K key, V value)
 void putAll(Map map)
 V remove(Object key)
 int size()
 Collection<v> values()

- HashTable là lớp đồng bộ (synchronized). Điều đó có nghĩa là HashTable chỉ cho phép tối đa một thread truy cập và xử lý dữ liệu tại một thời điểm. Thread này chiếm giữ HashTable và các Thread khác phải chờ cho đến khi Thread này truy cập và xử lý  xong.
 synchronized void clear()
 synchronized Object clone()
 boolean contains(Object value)
 synchronized boolean containsKey(Object key)
 synchronized boolean containsValue(Object value)
 synchronized Set<Entry<K, V>> entrySet()
 synchronized boolean equals(Object object)
 synchronized V get(Object key)
 synchronized int hashCode()
 synchronized boolean isEmpty()
 synchronized Set<k> keySet()
 synchronized Enumeration<k> keys()
 synchronized V put(K key, V value)
 synchronized void putAll(Map map)
 synchronized V remove(Object key)
 synchronized int size()
 synchronized String toString()
 synchronized Collection<v> values()


2. Khóa và Giá trị.
- HashMap cho phép lưu khóa và giá trị là NULL.
- HashTable không cho phép lưu khóa và giá trị là NULL.
package simplecodecjava.blogspot.com;

import java.util.HashMap;
import java.util.Hashtable;

public class HashMapvsHashTable {
 private HashMap<String, String> myHashMap = new HashMap<String, String>();
 private Hashtable<String, String> myHashTable = new Hashtable<String, String>();
 public HashMapvsHashTable() {
  try{
  myHashMap.put(null, null);
  myHashTable.put(null, null);
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 public static void main(String[]args){
  new HashMapvsHashTable();
 }
}
Output
java.lang.NullPointerException
 at java.util.Hashtable.put(Unknown Source)
 at simplecodecjava.blogspot.com.HashMapvsHashTable.<init>(HashMapvsHashTable.java:12)
 at simplecodecjava.blogspot.com.HashMapvsHashTable.main(HashMapvsHashTable.java:18)

3. Chèn và ánh xạ.
- HashMap là cài đặt của LinkedHashMap TreeMap. Vì vậy mà khi các phần từ được chèn vào trong HashMap theo một thứ tự và sắp xếp sự ánh xạ theo thứ tự tăng dần của khóa.
- HashTable thì ngược lại. Tức các phần tử được chèn vào trong HashTable không theo một thứ tự và sự ánh xạ cũng không theo thứ tự tăng dần của khóa.
4. Thành phần của Java Collection Framework.
- HashMap là một thành phần của Java Collection Framework.
- HashTable là lớp được dùng lại từ thành phần Java cũ nên không thuộc Java Collection Framework.
//HashTable được định nghĩa như sau
public class Hashtable extends Dictionary implements Map, Cloneable, Serializable {}
//HashMap được định nghĩa như sau
public class HashMap extends AbstractMap implements Map, Cloneable, Serializable {}
5. Cải tiến
 HashMap khắc phục một vài thiếu sót của HashTable. HashTable có phương thức contains(Object value) sẻ trả về true nếu HashTale có chứa đối tượng value. Trong khi đó HashMap có hai phương thức: phương thức containsKey(Object key) trả về true nếu HashMap có chứa đối tượng khóa, phương thức containValue(Object value) trả về true nếu HashMap có chứa đối tượng giá trị.
Sử dụng HashMap và HashTable.
1. Như so sánh ở trên sự khác nhau quan trọng nhất của HashMap HashTable là khả năng đồng bộ. Khi muốn sự thực thi của các luồng diễn ra an toàn thì nên sử dụng HashTable.
2. Sự đồng bộ sẽ làm giảm hiệu năng của chương trình vì vậy việc đồng bộ các luồng (synchromized) nên được tránh trừ trường hợp thực sự cần thiết. Do đó trong trường chương trình có nhiều Thread không đọc và ghi dữ liệu đồng thời thì nên sử dụng HashMap.

Thursday, December 31, 2015

[Java] Tạo file trong Java

Bài viết này sẽ trình bày cách tạo một file trong Java bằng phương thức createNewFile(). Phương thức này sẽ tạo ra một file rỗng. Nếu folder của đường dẫn tạo file chưa có file thì phương thức sẽ trả về TRUE. Nếu folder của đường  dẫn tạo file đã có file tồn tại phương thức sẽ trả về FALSE. Phương thức creatNewFile() sẽ ném ra các exception sau:
- IOException - Nếu có lỗi xảy ra trong quá trình tạo file.
- SecurityException - Nếu tồn tại Security manager và phương thức SecurityManager.checkWrite(java.lang.String) không có quyền write vào file.
Chương trình cài đặt:
Chương trình sau sẽ tạo ra một file txt có tên là "newfile.txt" trong ổ C. Để tạo file ở một ổ đĩa bất kỳ chỉ cần thay thổi đường dẫn tạo file.
package simplecodecjava.blogspot.com;

import java.io.File;
import java.io.IOException;

public class CreateFileDemo {
 public static void main(String[] args) {
  try {
   File file = new File("C:\\newfile.txt");
   /*
    * Nếu trong ổ C chưa tồn tại file newfile.txt thì phương thức createNewFile() trả về true
    * Nếu file đã tồn tại thì phương thức createNewFile() trả về false.
    */
   boolean fvar = file.createNewFile();
   if (fvar) {
    System.out.println("File đã được tạo thành công");
   } else {
    System.out.println("File đã tồn tại");
   }
  } catch (IOException e) {
   System.out.println("Đã xảy ra lỗi:");
   e.printStackTrace();
  }
 }
}

Wednesday, December 30, 2015

[Java] Cắt String trong Java - Split String in Java.

Phương thức split() được sử dụng để cắt một String thành các String nhỏ dựa trên ký tự phân chia. Phương thức này có 2 biến thể.
*String[] split(String kytuphanchia): Kết quả trả về là một mảng string sau khi cắt input String đầu vào theo 'kytuphanchia'.
*String[] split(String kytuphanchia, int gioihan): Kết quả trả về là một mảng String có kích thước bằng gioihan. Ví dụ: split('kytuphanchia',3) sẽ trả về một mảng String có kích thước là 3 mặc dù String input đầu vào sau khi split theo 'kytuphanchia' có thể có kích thước lớn hơn 3. Khi gioihan là một số âm mảng array String trả về sẽ chứa tất cả các String có thể cắt được từ input String đầu vào. Khi goihan là 0 thì mảng array String trả về sẽ chứa không chứa ký tự string rỗng ở cuối. Nghe có vẻ khó hiểu nhưng bài viết sẽ phân tích về gioihan là số âm, gioihan bằng 0 ở ví dụ phía dưới.
Chương trình cài đặt:
package simplecodecjava.blogspot.com;

public class SplitExample {
 public static void main(String args[]) {
  String str = new String("28/12/2015/ /simplecodecjava.blogspot.com");
  System.out.println("split(String kytuphanchia):");
  String array1[] = str.split("/");
  for (String temp : array1) {
   System.out.println(temp);
  }
  System.out.println("split(String kytuphanchia, int gioihan) với gioihan=2:");
  String array2[] = str.split("/", 2);
  for (String temp : array2) {
   System.out.println(temp);
  }
  System.out.println("split(String kytuphanchia, int gioihan) với gioihan=0:");
  String array3[] = str.split("/", 0);
  for (String temp : array3) {
   System.out.println(temp);
  }
  System.out.println("split(String kytuphanchia, int gioihan) với gioihan=-5:");
  String array4[] = str.split("/", -5);
  for (String temp : array4) {
   System.out.println(temp);
  }
 }
}
Output:
split(String kytuphanchia):
28
12
2015
 
simplecodecjava.blogspot.com
split(String kytuphanchia, int gioihan) với gioihan=2:
28
12/2015/ /simplecodecjava.blogspot.com
split(String kytuphanchia, int gioihan) với gioihan=0:
28
12
2015
 
simplecodecjava.blogspot.com
split(String kytuphanchia, int gioihan) với gioihan=-5:
28
12
2015
 
simplecodecjava.blogspot.com
Kết quả của chương trình trên.
* Với trường hợp gioihan = 2 thì mảng String đầu ra có kích thước là 2. Do đó mà kết quả in ra {'28','12/2015/ /simplecodecjava.blogspot.com'}
* Với trường hợp gioihan = -5 và gioihan=0 cho cùng một kết quả {'28','12','2015','','simplecodecjava.blogspot.com'}
* Nếu thay input String đầu vào:
String str = new String("28/12/2015/ /simplecodecjava.blogspot.com//");
Ta sẽ thấy kết quả chương trình có sự khác biệt giữa gioihan=-5 và gioihan=0:
split(String kytuphanchia):
28
12
2015
 
simplecodecjava.blogspot.com
split(String kytuphanchia, int gioihan) với gioihan=2:
28
12/2015/ /simplecodecjava.blogspot.com//
split(String kytuphanchia, int gioihan) với gioihan=0:
28
12
2015
 
simplecodecjava.blogspot.com
split(String kytuphanchia, int gioihan) với gioihan=-5:
28
12
2015
 
simplecodecjava.blogspot.com


* gioihan = -5: input string đầu vào đã được cắt ra thành {'28','12','2015',' ','simplecodecjava.blogspot.com',' ',' '}.
* gioihan = 0: input string đầu vào đã được cắt ra thành {'28','12','2015',' ','simplecodecjava.blogspot.com'}.
Mảng string thu được sau khi cắt với gioihan = -5 so với gioihan = 0 nhiều hơn 2 string rỗng bởi 2 ký tự cuối {//} trong chuỗi input String đầu vào cũng bị cắt ra và tạo thành 2 String rỗng.

Chú ý:
*Khi kytuphanchia là những ký tự đặc biệt. thì cần phải thêm '\\' vào đằng  trước.
Phân chia theo dấu '.' được viết thành: string.split('\\.');
Phân chia theo dấu '^' được viết thành: string.split('\\^');
Phân chia theo khoảng trắng ' ' được viết thành: string.split('\\s');
Phân chia theo dấu '|' được viết thành: string.split('\\|');
* Khi muốn cắt String theo chữ số dùng '\\d+'
String str = new String("abc123def456ghj");
  System.out.println("split(String kytuphanchia):");
  String array1[] = str.split("\\d+");
  for (String temp : array1) {
   System.out.println(temp);
  }
Output:
split(String kytuphanchia):
abc
def
ghj

* Khi muốn cắt String theo chữ cái dùng '[a-zA-Z]+'
String str = new String("0abc123def456ghj");
  System.out.println("split(String kytuphanchia):");
  String array1[] = str.split("[a-zA-Z]+");
  for (String temp : array1) {
   System.out.println(temp);
  }
Output:
split(String kytuphanchia):
0
123
456

Tuesday, December 29, 2015

[Java] Enum trong Java

1. Enum
Enum là một kiểu dữ liệu đặc biệt, về cơ bản enum là một tập các hằng số.
Đây là một ví dụ về enum:
public enum Directions{
  EAST, 
  WEST, 
  NORTH, 
  SOUTH
}
Ở đây Directions là một kiểu enum, là một tập chứa 4 hằng số EAST, WEST, NORTH và SOUTH.
2. Gán giá trị cho kiểu enum.
Directions dir = Directions.NORTH;
Biến dir có kiểu là Direction, có thể nhận bất kỳ giá trị nào trong bốn giá trị (EAST, WEST, NORTH, SOUTH). Trong ví dụ trên dir nhận giá trị NORTH.
3. Sử dụng enum trong mệnh đề if-else.
Biến có kiểu enum có thể được dùng trong mệnh đề if-else.
public enum Directions{
   EAST, 
   WEST, 
   NORTH, 
   SOUTH
}
public class EnumDemo
{
   public static void main(String args[]){
 Directions dir = Directions.NORTH;  
 if(dir == Directions.EAST) {
     System.out.println("Direction: East");
 } else if(dir == Directions.WEST) {
     System.out.println("Direction: West");
   } else if(dir == Directions.NORTH) {
       System.out.println("Direction: North");
       } else {
  System.out.println("Direction: South");
       }
   }
}
Output:
Direction: North
4. Sử dụng enum trong mệnh đề Swich-Case
public enum Directions{
   EAST, 
   WEST, 
   NORTH, 
   SOUTH
}
public class EnumDemo
{
   Directions dir;
   public EnumDemo(Directions dir) {
      this.dir = dir;
   }
   public void getMyDirection() {
     switch (dir) {
       case EAST:
          System.out.println("In East Direction");
          break;
                    
       case WEST:
          System.out.println("In West Direction");
          break;
                         
       case NORTH: 
          System.out.println("In North Direction");
          break;
                        
       default:
          System.out.println("In South Direction");
          break;
     }
   }
    
    public static void main(String[] args) {
        EnumDemo obj1 = new EnumDemo(Directions.EAST);
        obj1.getMyDirection();
        EnumDemo obj2 = new EnumDemo(Directions.SOUTH);
        obj2.getMyDirection();
    }
}
Output:
In East Direction
In South Direction
Xem các giá trị của enum.
class EnumDemo
{
    public static void main(String[] args) {
     for (Directions dir : Directions.values()) {
         System.out.println(dir);
     }
    }
}
Output:
EAST
WEST
NORTH 
SOUTH

[Java] Inner class trong Java

a. Định nghĩa một Inner class.
Một Inner class được định nghĩa trong cặp dấu "{}" của Outer class.
package simplecodecjava.blogspot.com;

//Outer class - chứa Inner class
public class OuterClassDemo {
 private int myVar = 1;

 // Định nghĩa Inner class
 class InnerClassDemo {
  public void seeOuter() {
   System.out.println("Value of myVar is :" + myVar);
  }
 } // close Định nghĩa Inner class
} // close Định nghĩa Outer class
Inner class được định nghĩa trong cặp dấu "{}" nên Inner class được coi là một thành phần của Outer class, do đó Inner class cũng có thể định nghĩa phạm vi truy cập như đối với các biến của Outer class như: abstract, final, public, protected, private, static, đồng thời Inner class cũng có thể truy cập tới các các biến này. Ở ví dụ trên biến myVar được truy cập từ trong phương thức của Inner class.
b. Khởi tạo một đối tượng của Inner class.
Có 2 cách để khởi tạo một đối tượng có kiểu Inner class.
Khởi tạo Inner class thông qua khởi tạo Outer class.
Vì Inner class là một thành phần của Outer class do đó Inner class tồn tại bên trong một đối tượng của Outer class.
package simplecodecjava.blogspot.com;

//Outer class - chứa Inner class
public class OuterClassDemo {
 private int x = 1;

 public void innerInstance() {
  InnerClassDemo inner = new InnerClassDemo();
  inner.seeOuter();
 }

 public static void main(String args[]) {
  OuterClassDemo obj = new OuterClassDemo();
  obj.innerInstance();
 }

 // Định nghĩa Inner class
 class InnerClassDemo {
  public void seeOuter() {
   System.out.println("Giá strị của x is :" + x);
  }
 } // close định nghĩa Inner class
} // close Outer class
Output:
Giá trị của x is :1
Khơi tạo trực tiếp Inner class không cần khởi tạo Outer class
Inner class cũng được khởi tạo bằng từ khóa new.
 public static void main(String args[]) {
  OuterClassDemo.InnerClassDemo inner = new OuterClassDemo().new InnerClassDemo();
  inner. seeOuter();
 }

Friday, December 18, 2015

[Java] Loại bỏ phần tử lặp trong ArrayList.

Trong bài viết này chúng ta sẽ học cách loại bỏ phần tử lặp có trong ArrayList. Các bước thực hiện như sau.
  1. Copy tất cả các phần tử của ArrayList cho LinkedHashSet.Tại sao lại là LinkedHashSet ? Bởi LinkedHashSet có thể loại bỏ các phần tử lặp và giữ cho việc chèn các phần tử theo thứ tự.
  2. Loại bỏ tất cả các phần tử của ArrayList.
  3. Copy tất cả các phần tử của LinkedHashSet cho ArrayList.
Chương trình cài đặt loại bỏ các phần tử lặp có trong ArrayList.
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
 
public class RemoveDuplicates {
 public static void main(String[]args){
  List<string> list = new ArrayList<string>();
  list.add("Hà Nội");
  list.add("Huế");
  list.add("Đà Nẵng");
  list.add("TP. Hồ Chí Minh");
  list.add("Hà Nội");
  System.out.println("Trước khi loại bỏ phần tử lặp:");
  for (String item : list) {
   System.out.println(item);
  }
  LinkedHashSet<string> linkedHashSet = new LinkedHashSet<string>();
  //copy các phần tử của list cho linkedHashset.
  linkedHashSet.addAll(list);
  //Loại bỏ tất cả các phần tử của ArrayList
  list.clear();
  //Copy tất cả các phần tử của LinkedHashSet cho ArrayList.
  list.addAll(linkedHashSet);
  System.out.println("Sau khi loại bỏ phần tử lặp:");
  for (String item : list) {
   System.out.println(item);
  }
 }
}
Output:
Trước khi loại bỏ phần tử lặp:
Hà Nội
Huế
Đà Nẵng
TP. Hồ Chí Minh
Hà Nội
Sau khi loại bỏ phần tử lặp:
Hà Nội
Huế
Đà Nẵng
TP. Hồ Chí Minh

[Java] Hàm Join trong Java

Hàm Join được sử dụng để giữ cho quá trình thực thi của hàm đang chạy không bị gián đoạn bởi các thread khác, nói một cách khác nếu một thead đang chạy các thread khác sẽ phải chờ cho đến khi thread đó thực thi xong.
Tạo sao lại sử dụng hàm Join.
Trong một chương trình Java thường có nhiều hơn một thread,trong đó có main thread - có chức năng khởi tạo và kích hoạt để chạy các thread khác, tuy nhiên các main thread không đảm bảo các thread thực thi và kết thúc theo đúng thứ tự mà chúng đã được khởi chạy. Hãy xem ví dụ sau:
1. Khi không sử dụng hàm Join.
Ở đây có 3 thread th1, th2, th3. Mặc dù các thread được khởi chạy theo thứ tự th1>th2>th3 nhưng kết thúc thực thi của 3 thread trên không theo thứ tự th1>th2>th3. Ở mỗi thời điển chạy chương trình có thể nhận được các kết quả khác nhau.
public class JoinExample {
 public static void main(String[]args){
  Thread th1 = new Thread(new MyThread(),"th1");
  Thread th2 = new Thread(new MyThread(),"th2");
  Thread th3 = new Thread(new MyThread(),"th3");
  th1.start();
  th2.start();
  th3.start();
 }
}
class MyThread implements Runnable {
 public void run() {
  Thread t = Thread.currentThread();
  System.out.println("Bắt đầu thread: " + t.getName());
  try{
   Thread.sleep(4000);
  }catch(InterruptedException e){
   e.printStackTrace();
  }
  System.out.println("Kết thúc thread:" + t.getName());
 }
}
Output:
Bắt đầu thread: th1
Bắt đầu thread: th3
Bắt đầu thread: th2
Kết thúc thread:th3
Kết thúc thread:th1
Kết thúc thread:th2
2. Khi sử dụng hàm Join
Câu hỏi đưa ra là: Làm thế nào để các thread thực thi và kết thúc theo đúng thứ tự mà chúng được khởi chạy. Câu trả lời là: Sử dụng hàm Join sẵn có của Java. Giả sử thứ tự của các thread là: thread1 chạy trước, sau đó là thread2, thread3 chạy sau cùng.
Chương trình cài đặt sử dụng hàm Join như sau:
public class JoinExample {
 public static void main(String[]args){
  Thread th1 = new Thread(new MyThread(),"th1");
  Thread th2 = new Thread(new MyThread(),"th2");
  Thread th3 = new Thread(new MyThread(),"th3");
  //khởi chạy thread 1.
  th1.start();
  try {
   th1.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  //khởi chạy thread 2.
  th2.start();
  try {
   th2.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  //khởi chạy thread 3.
  th3.start();
  try {
   th3.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}
class MyThread implements Runnable {
 public void run() {
  Thread t = Thread.currentThread();
  System.out.println("Bắt đầu thread: " + t.getName());
  try{
   Thread.sleep(4000);
  }catch(InterruptedException e){
   e.printStackTrace();
  }
  System.out.println("Kết thúc thread:" + t.getName());
 }
}
Khi chạy chương trình trên, ta sẽ thấy kết quả in ra mà hình theo thứ tự  th1>th2>th3
Output:
Bắt đầu thread: th1
Kết thúc thread:th1
Bắt đầu thread: th2
Kết thúc thread:th2
Bắt đầu thread: th3
Kết thúc thread:th3
Khi so sánh với chương trình cài đặt không sử dụng hàm Join, thread2, thread3, chưa khởi chạy ngay được gọi bằng lệnh th2.start(), th3.start() , thead2 và thread3 đã đợi cho đến khi thread1 thực thi xong mới khởi chạy. Tương tự khi thread2 chạy thì thread3 vẫn phải đợi cho đến khi thread2 thực thi xong. Do đó mà kết quả in ra màn hình theo đúng thứ tự th1>th2>th3 mà chúng đã được khởi chạy.

[Java] Có thể khởi chạy Thread 2 lần không ?

Có thể khởi  chạy Thread 2 lần không ? Câu trả lời là không. Một thread khi đã khởi chạy thì nó không thể được khởi chạy lại. Nếu gọi khởi chạy thread lần thứ 2 Java sẽ ném ra một exception IllegalThreadStateException. Hãy xem ví dụ sau:
public class ThreadTwiceExample implements Runnable {
   public void run(){  
 Thread t = Thread.currentThread();
        System.out.println(t.getName()+" đang thực thi.");
      
   }  
   public static void main(String args[]){  
 Thread th1 = new Thread(new ThreadTwiceExample(), "thread1"); 
 th1.start();  
 th1.start();  
   } 
}
Khi chạy chương trình trên sẽ có thông báo lỗi như sau:
Exception in thread "main" thread1 đang thực thi.
java.lang.IllegalThreadStateException
 at java.lang.Thread.start(Unknown Source)
 at ThreadTwiceExample.main(ThreadTwiceExample.java:10)
Nhìn vào kết quả của chương trình trên phương thức run đã được gọi khi lệnh sau được thực thi:
th1.start();
Nhưng Java ném ra một lỗi khi phương thức trên được gọi đến lần thứ 2.

[C/C++] Ép chữ thường thành chữ hoa trong C/C++

Chương trình sau dùng để chuyển đổi chữ thường thành  chữ hoa. Logic của chương trình như sau: Tất cả các chữ cái thường (a đến z) có giá trị trong bảng mã ASCII nằm trong khoảng 97 đến 122 và các chữ cái hoa tương ứng (A đến Z) có giá trị nhỏ hơn 32 trong bảng mã ASCII.
Ví dụ: chữ cái 'a' trong bảng mã ASCII có giá trị là 97 và chữ cái 'A' trong bảng mã ASCII có giá trị 65 (97-32). Các chữ cái khác cũng theo quy tắc tương tự.
Theo logic đó chương trình cài đặt thực hiện ép chữ cái thường thành chữ cái hoa.
#include<iostream>
#include<conio.h>
#include<string.h>
using namespace std;
int main(){
 char inputString[] = "simplecodecjava.blogspot.com";
 char outputString[256];
 for(int index = 0; index < sizeof(inputString); index++){
  if(inputString[index] >='a' && inputString[index] <='z'){
   //ký tự là chữ cái thường.
   outputString[index] = inputString[index] - 32;
  }else {
   //ký tự là ký tự hoa hoặc là ký tự đặc biệt.
   outputString[index] = inputString[index];
  }
 }
 cout<<"string chữ hoa: " << outputString;
 _getch();
 return 0;
}

Wednesday, December 2, 2015

JSON Tutorial - Kiến thức căn bản về JSON.

1. JSON
JSON là viết tắt của JavaScript Object Notation. JSON được sử dụng để truyền dữ liệu giữa Server và Client, XML cũng được sử dụng để truyền dữ liệu giữa Server và Client. Tuy nhiên việc truyền dữ liệu bằng JSON Objects có một vài lợi thế so với XML. Bài viết này sẽ đưa ra cái nhìn tổng quan về JSON và cách sử dụng JSON.
Dữ liệu kiểu JSON là một cặp key - value.
var student = {
   "firstName" : "Hạnh",
   "lastName" : "Nguyễn",
   "age" :  "23"
}; 
Với các chú ý sau:
- Chuỗi JSON được được bắt đầu và kết thúc bằng cặp dấu '{}'.
- Các key và value của JSON được đặt trong dấu nháy kép   " " . Nếu value có chứa dấu nháy kép ' " ' thì cần phải đặt ký tự ' \ ' trước dấu nháy kép. Ví dụ value = "simplecodecjava.blogspot.com" thì khi định nghĩa dữ liệu trong JSON phải viết là \"simplecodecjava.blogspot.com\".
- Nếu có nhiều dữ liệu ( nhiều cặp key-value) thì ta dùng dấu ' ,' để ngăn cách các cặp dữ liệu.
- Các key của JSON thường được đặt là các chữ cái không dấu, chữ số, dấu '_' và không có khoảng trắng.
2. Đặc trưng của JSON
- Là kiểu dữ liệu nhẹ.
- Không phụ thuộc vào ngôn ngữ.
- Dễ đọc và viết.
- Viết dựa trên text, nên có thể dễ dàng hiểu nội dung của JSON.
 3. Tại sao sử dụng JSON.
 - Cấu trúc chuẩn: JSON được định nghĩa theo một cấu trúc chuẩn nó giúp cho Developer dễ dàng đọc, viết và hiểu. Vì vậy mà các Developer thường chọn JSON.
- Là kiểu dữ liệu nhẹ: Khi làm việc với AJAX cần phải load dữ liệu nhanh và đồng bộ mà không cần phải gửi request lại. Vì JSON là kiểu dữ liệu nhẹ nên việc tải và request dữ liệu nhanh hơn.
- Khả năng linh hoạt: JSON không phụ thuộc vào ngôn ngữ, điều đó có nghĩa là nó hoạt động tốt với hầu hết tất cả các ngôn ngữ lập trình hiện đại. Giả xử khi cần thay đổi ngôn ngữ lập trình bên phía server, trong trường hợp này việc thay đổi kiến trúc của JSON trở nên dễ dàng cho mọi ngôn ngữ lập trình.
4. JSON vs. XML
Hãy xem cách mà JSON và XML lưu trữ 4 bản ghi học sinh .
Dữ liệu dưới dạng JSON.
{"students":[
   {"name":"Tuấn", "age":"23", "city":"Hà Nội"},
   {"name":"Đạt", "age":"28", "city":"Đà Nẵng"},
   {"name":"Lan", "age":"32", "city":"Thừa Thiên Huế"},
   {"name":"Yến", "age":"28", "city":"TP.Hồ Chí Minh"}
]}
Dữ liệu dưới dạng XML.
<students>
  <student>
    <name>Tuấn</name> <age>23</age> <city>Hà Nội</city>
  </student>
  <student>
    <name>Đạt</name> <age>28</age> <city>Đà Nẵng</city>
  </student>
  <student>
    <name>Lan</name> <age>32</age> <city>Thừa Thiên Huế</city>
  </student>
  <student>
    <name>Yến</name> <age>28</age> <city>TP.Hồ Chí Minh</city>
  </student>
</students>
Có thể dễ dàng thấy rằng dữ liệu dưới dạng JSON thì  nhẹ hơn so với dữ liệu dưới dạng XML.
5. Kiến trúc dữ liệu kiểu và cách đọc JSON.
a. Đối tượng JSON.
var person= {
  "name" : "ZappyMans",
  "age" = "24",
  "website" = "simplecodecjava.blogspot.com"
};
Để truy cập đữ liệu cho đối tượng JSON ở trên chúng ta viết key theo sau tên đối tượng theo mẫu sau:
<đối_tượng>.<key>
ví dụ:
Tên của đối tượng person: person.name
Tuổi của đối tượng person: person.age
Website của đối tượng person: person.website
b. Mảng đối tượng JSON.
Phần trên trình bày cách lưu trữ thông tin của một đối tượng person. Giả sử muốn lưu thông tin của nhiều hơn một đối tượng, trong trường hợp này chúng ta dùng mảng.
var students = [{
   "name" : "Lan",
   "age" :  "23",
   "gender" : "Nữ"
},
{
   "name" : "Tuấn",
   "age" : "24",
   "gender" : "Nam"
},
{
   "name" : "Yến",
   "age" : "21",
   "gender" : "Nữ"
}];
Để truy cập và lấy ra dữ liệu của một phần tử trong mảng, ta chèn thêm chỉ số và phần tử của mảng.
Tên của học sinh thứ 1: students[0].name // Lan
Tuổi của học sinh thứ 2: students[1].age //24
Giới tính của học sinh thứ 3: students[2].gender //Nữ 
c. Khai báo JSON theo cấu trúc lồng nhau.
Cách khác để truy cập và lấy ra dữ liệu của một phần tử của trong một mảng JSON được khai báo lồng nhau.
var students = {
  "Lan" : {
  "name" : "Lan",
  "age" :  "23",
  "gender" : "Nữ" 
},

"Tuấn" : {
  "name" : "Tuấn",
  "age" : "24",
  "gender" : "Nam"
},

"Yến" : {
  "name" : "Yến",
  "age" : "21",
  "gender" : "Nữ"
}
}
Tuổi của Lan : student.Lan.age // 23
Giới tính của Tuấn: student.Tuấn.gender // Nam
6. JSON và JavaScript.
JSON được xem là 'tập con' của JavaScript nhưng không có nghĩa là nó không thể dùng được với các ngôn ngữ khác. Trên thực tế JSON được sử dụng rất hiệu quả với PHP, Perl, Python, Ruby, Java, Ajax và nhiều ngôn ngữ nữa.
Để chứng minh JSON có thể sử dụng với JavaScript, hãy xem ví dụ sau.
a. Đọc dữ liệu từ file JSON và chuyển đổi thành JavaScript Object.
var student = {
   "firstName" : "Hạnh",
   "lastName" : "Nguyễn",
   "age" :  "23"
}; 
Để chuyển đối tượng JSON Object phía trên thành JavaScript Object sử dụng phương thức parse của JSON.
var javaScriptObject = JSON.parse(student); 
b. Chuyển đối tượng JavaScript Object thành JSON text 
Sử dụng phương thức stringify.
 var jsonObject = JSON.stringify(myObject);

Monday, November 30, 2015

[Java] Sắp xếp ArrayList trong Java

1. Sắp xếp mảng String ArrayList
Để sắp  xếp ArrayList có kiểu dữ liệu là String, ta dùng method Collections.sort(arraylist), dữ liệu được chứa trong ArrayList sẽ được sắp xếp theo thứ tự alphabetic.
Ví dụ.
package simplecodecjava.blogspot.com;

import java.util.ArrayList;
import java.util.Collections;

public class SortingInArrayList {
 public static void main(String[] args){
  ArrayList<String> arrayList = new ArrayList<>();
  arrayList.add("Hà Nội");
  arrayList.add("Đà Nẵng");
  arrayList.add("Nha Trang");
  arrayList.add("TP.Hồ Chí Minh");
  System.out.println("Trước khi sắp xếp");
  for(String item: arrayList){
   System.out.println(item);
  }
  Collections.sort(arrayList);
  System.out.println("Sau khi sắp xếp");
  for(String item: arrayList){
   System.out.println(item);
  }
 }
}
Kết quả output:
Trước khi sắp xếp
Hà Nội
Đà Nẵng
Nha Trang
TP.Hồ Chí Minh
Sau khi sắp xếp
Hà Nội
Nha Trang
TP.Hồ Chí Minh
Đà Nẵng
*note: Trong bảng mã Unicode ký tự Đ đứng sau ký tự T 
2. Sắp xếp mảng Interger ArrayList.
Tương tự như với mảng String, phương thức Collections.sort(arraylist) cũng được dùng để sắp xếp mảng Interger.
Ví dụ
package simplecodecjava.blogspot.com;

import java.util.ArrayList;
import java.util.Collections;

public class SortingInArrayList {
 public static void main(String[] args){
  ArrayList<Integer> arrayList = new ArrayList<>();
  arrayList.add(10);
  arrayList.add(2);
  arrayList.add(221);
  arrayList.add(991);
  System.out.println("Trước khi sắp xếp");
  for(Integer item: arrayList){
   System.out.println(item);
  }
  Collections.sort(arrayList);
  System.out.println("Sau khi sắp xếp");
  for(Integer item: arrayList){
   System.out.println(item);
  }
 }
}
Output:
Trước khi sắp xếp
10
2
221
991
Sau khi sắp xếp
2
10
221
991
3. Sắp xếp mảng Object ArrayList
Phương thức Collections.sort(arraylist) cũng được dùng để sắp xếp mảng đối tượng, tuy nhiên đối tượng cần phải là lớp thực thi của Comparable interaface hoặc viết lại phương thức compare của Comparator interface.
Trước tiên hãy xem ví dụ sau khi dùng Collections.sort(arraylist) mà chưa cài đặt bằng một trong hai cách trên.
package simplecodecjava.blogspot.com;

public class Student {
 private int MSV;
 private String ten;
 private int namsinh;
 private String khoa;
 public Student(int MSV, String ten, int namsinh, String khoa){
  this.MSV = MSV;
  this.ten = ten;
  this.namsinh = namsinh;
  this.khoa = khoa;
 }
 @Override
 public String toString() {
  return MSV + " - " + ten + " - " + namsinh + " - " + khoa;
 }
}
Main chương trình:
package simplecodecjava.blogspot.com;

import java.util.ArrayList;
import java.util.Collections;

public class SortingInArrayList {
 public static void main(String[] args){
  ArrayList<Student> arrayList = new ArrayList<Student>();
  arrayList.add(new Student(1, "Cảnh", 1991, "Công nghệ thông tin"));
  arrayList.add(new Student(5, "Tuấn", 1992, "Công nghệ thông tin"));
  arrayList.add(new Student(9, "Việt", 1994, "Điện tử viễn thông"));
  arrayList.add(new Student(1, "Tú Anh", 1993, "Công nghệ thông tin"));
  arrayList.add(new Student(1, "Liên", 1991, "Điện tử viễn thông"));
  arrayList.add(new Student(1, "Hiệp", 1990, "Điện tử viễn thông"));
  arrayList.add(new Student(1, "Quỳnh", 1992, "Công nghệ thông tin"));
  System.out.println("Trước khi sắp xếp");
  for(Student item: arrayList){
   System.out.println(item);
  }
  Collections.sort(arrayList);
  System.out.println("Sau khi sắp xếp");
  for(Student item: arrayList){
   System.out.println(item);
  }
 }
}
Với chương trình main trên, sẽ có thông báo lỗi ở dòng
Collections.sort(arrayList);
Với lỗi thông báo như sau:
Bound mismatch: The generic method sort(List) of type Collections is not applicable for the arguments 
 (ArrayList). The inferred type Student is not a valid substitute for the bounded parameter >
Lỗi trên có thể được fix bằng một trong hai cách sau:
3.1 Cài đặt Class Student là lớp thực thi của Comparable interaface.
package simplecodecjava.blogspot.com;

public class Student implements Comparable<Student>{
 private int MSV;
 private String ten;
 private int namsinh;
 private String khoa;
 public Student(int MSV, String ten, int namsinh, String khoa){
  this.MSV = MSV;
  this.ten = ten;
  this.namsinh = namsinh;
  this.khoa = khoa;
 }
 @Override
 public String toString() {
  return MSV + " - " + ten + " - " + namsinh + " - " + khoa;
 }
 // sắp xếp sinh viên theo tên và theo khoa.
 @Override
 public int compareTo(Student o) {
  if(this.khoa.compareTo(o.khoa)== 0){
   return this.ten.compareTo(o.ten);
  }else{
   return this.khoa.compareTo(o.khoa);
  }
 }
}
Output: Sắp  xếp sinh viên theo khoa và theo tên theo thứ tự tăng dần.
Trước khi sắp xếp
1 - Cảnh - 1991 - Công nghệ thông tin
5 - Tuấn - 1992 - Công nghệ thông tin
9 - Việt - 1994 - Điện tử viễn thông
10 - Tú Anh - 1993 - Công nghệ thông tin
22 - Liên - 1991 - Điện tử viễn thông
17 - Hiệp - 1990 - Điện tử viễn thông
23 - Quỳnh - 1992 - Công nghệ thông tin
Sau khi sắp xếp
1 - Cảnh - 1991 - Công nghệ thông tin
23 - Quỳnh - 1992 - Công nghệ thông tin
5 - Tuấn - 1992 - Công nghệ thông tin
10 - Tú Anh - 1993 - Công nghệ thông tin
17 - Hiệp - 1990 - Điện tử viễn thông
22 - Liên - 1991 - Điện tử viễn thông
9 - Việt - 1994 - Điện tử viễn thông
3.2 Viết lại phương thức compare của Comparator interface.
Với cách này chúng ta không cần cài đặt Student là lớp thực thi từ Comparator interface như ở 3.1, thay vào đó phương thức compare của Comparator interace được viết lại như sau:
package simplecodecjava.blogspot.com;
import java.util.Comparator;
public class Student{
 private int MSV;
 private String ten;
 private int namsinh;
 private String khoa;
 public Student(int MSV, String ten, int namsinh, String khoa){
  this.MSV = MSV;
  this.ten = ten;
  this.namsinh = namsinh;
  this.khoa = khoa;
 }
 @Override
 public String toString() {
  return MSV + " - " + ten + " - " + namsinh + " - " + khoa;
 }
 public static Comparator<Student> compare = new Comparator<Student>() {

  @Override
  public int compare(Student o1, Student o2) {
   if(o1.khoa.compareTo(o2.khoa)== 0){
    return o1.ten.compareTo(o2.ten);
   }else{
    return o1.khoa.compareTo(o2.khoa);
   }
  }
 };
 }
Main chương trình:
package simplecodecjava.blogspot.com;

import java.util.ArrayList;
import java.util.Collections;

public class SortingInArrayList {
 public static void main(String[] args){
  ArrayList<Student> arrayList = new ArrayList<Student>();
  arrayList.add(new Student(1, "Cảnh", 1991, "Công nghệ thông tin"));
  arrayList.add(new Student(5, "Tuấn", 1992, "Công nghệ thông tin"));
  arrayList.add(new Student(9, "Việt", 1994, "Điện tử viễn thông"));
  arrayList.add(new Student(10, "Tú Anh", 1993, "Công nghệ thông tin"));
  arrayList.add(new Student(22, "Liên", 1991, "Điện tử viễn thông"));
  arrayList.add(new Student(17, "Hiệp", 1990, "Điện tử viễn thông"));
  arrayList.add(new Student(23, "Quỳnh", 1992, "Công nghệ thông tin"));
  System.out.println("Trước khi sắp xếp");
  for(Student item: arrayList){
   System.out.println(item);
  }
  Collections.sort(arrayList, Student.compare);
  System.out.println("Sau khi sắp xếp");
  for(Student item: arrayList){
   System.out.println(item);
  }
 }
}
Output:
Trước khi sắp xếp
1 - Cảnh - 1991 - Công nghệ thông tin
5 - Tuấn - 1992 - Công nghệ thông tin
9 - Việt - 1994 - Điện tử viễn thông
10 - Tú Anh - 1993 - Công nghệ thông tin
22 - Liên - 1991 - Điện tử viễn thông
17 - Hiệp - 1990 - Điện tử viễn thông
23 - Quỳnh - 1992 - Công nghệ thông tin
Sau khi sắp xếp
1 - Cảnh - 1991 - Công nghệ thông tin
23 - Quỳnh - 1992 - Công nghệ thông tin
5 - Tuấn - 1992 - Công nghệ thông tin
10 - Tú Anh - 1993 - Công nghệ thông tin
17 - Hiệp - 1990 - Điện tử viễn thông
22 - Liên - 1991 - Điện tử viễn thông
9 - Việt - 1994 - Điện tử viễn thông

Thursday, November 12, 2015

[Java] ArrayList trong Java

ArrayList là một Class implement (thực thi) của List Interface, được sử dụng phổ biến bởi khả năng linh động của nó. Hầu hết tất cả các developer chọn ArrayList thay vì Array truyền thống như trong C/C++.
Vấn đề với Array đó là kích thước cố định của nó, nếu Array được khai báo có kích thước n phần tử thì khi Array đã chứa đầy n phần tử thì ta không thể chèn thêm bất kỳ phần tử nào nữa. Còn ArrayList thì khác ta có thể chèm thêm tùy ý mà không cần lo lắng là ArrayList sẽ bị đầy, chính vì đặc tính này mà giúp cho ArrayList phổ biến hơn Array.
Ví dụ về ArrayList.
import java.util.ArrayList;
public class ArrayListExample {
 public static void main(String args[]) {
       /*
        *Tạo ArrayList: Thêm String
        *Dữ liệu được thêm vào có kiểu dữ liệu là String
        **/
    ArrayList<String> obj = new ArrayList<String>();
    /*This is how elements should be added to the array list*/
    obj.add("Hà Nội");
    obj.add("Đà Nẵng");
    obj.add("TP Hồ Chí Minh");
    obj.add("Hoàng Sa");
    obj.add("Trường Sa");
    System.out.println("ArrayList chứa những String sau.:"+obj);
    /*Thêm String mới vào các vị trí*/
    obj.add(0, "Nha Trang");
    obj.add(1, "Đà Lạt");
    /*Loại bỏ String khỏi ArrayList*/
    obj.remove("Đà Nẵng");
    obj.remove("TP Hồ Chí Minh");
    System.out.println("ArrayList mới nhận được:"+obj);
    /*Loại bỏ String ở vị trí 1*/
    obj.remove(1);
    System.out.println("ArrayList mới nhận được:"+obj);
    }
}
Kết quả chương trình:
ArrayList chứa những String sau.:[Hà Nội, Đà Nẵng, TP Hồ Chí Minh, Hoàng Sa, Trường Sa]
ArrayList mới nhận được:[Nha Trang, Đà Lạt, Hà Nội, Hoàng Sa, Trường Sa]
ArrayList mới nhận được:[Nha Trang, Hà Nội, Hoàng Sa, Trường Sa]
Các Method của ArrayList class.
1. add(Object o): Thêm một đối tượng vào trong ArrayList.
obj.add("Hello");
Thêm String "Hello" vào cuối ArrayList
2. add(int index, Object o): Thêm một đối tượng vào trong ArrayList ở vị trí index.
obj.add(2,"Hello");
Thêm String "Hello" vào vị trí thứ 2 của ArrayList.
3. boolean remove(Object o): Loại bỏ đối tượng o ra khỏi ArrayList.
obj.remove("Hello");
Loại bỏ String "Hello" trong ArrayList. Nếu  có String "Hello" phương thức sẽ trả về TRUE, nếu không có phương thức sẽ trả về FALSE.
4. E remove(int index): Loại bỏ đối tượng ở vị trí index.
obj.remove(1);
Loại bỏ đối  tượng ở vị trí index = 1 trong ArrayList. Kết quả trả về đối tượng ở vị trí số 1.
5. E set(int index, Object o): Được dùng để update một đối tượng, sẽ thay thế đối tượng ở vị trí index bằng đối tượng o. Phương thức trả về đối tượng ở vị trí index trước khi bị thay thế bởi đối tượng o.
obj.set(1,"Hello");
Thay thế String ở vị trí 1 bằng String "Hello", phương thức trả về String ở vị trí 1 trước khi bị thay thế bởi String "Hello".
6. int indexOf(Object o): Đưa ra vị trí của đối tượng o trong ArrayList. Nếu đối tượng không tìm thấy trong ArrayList method sẽ trả về -1.
obj.indexOf("Hello");
Trả về vị trí của String "Hello" có trong ArrayList. Nếu không có String "Hello" trong ArrayList, phương thức sẽ trả về -1.
7. Object get(int index): Trả về đối tượng của ArrayList ở vị trí index.
obj.get(1);
Trả về đối tượng ở vị trí 1.
8. int size(): Trả về số đối tượng có trong ArrayList.
obj.size();
9. boolean contains(Object o): Thực hiện kiểm tra đối tượng o có trong ArrayList hay không. Nếu có phương thức sẽ trả về TRUE, nếu không có phương thức sẽ trả về FALSE.
obj.contains("Hello");
Nếu ArayList có chứa String "Hello" phương thức sẽ trả về TRUE, nếu không chứa sẽ trả về FALSE.
10. clear(): Loại bỏ tất cả các đối tượng có trong ArrayList.
obj.clear();
Nếu bạn có câu hỏi hay góp ý xin hãy để lại ý kiến trong phần comment của bài viết.

Wednesday, November 11, 2015

[Java] HashMap trong Java và ví dụ

HashMap còn được gọi là mảng băm chứa cặp khóa - giá trị và được ký hiệu  HashMap <Key, Value> hoặc HashMap <K, V> . HashMap là implements(thực thi) của Map Interface. HaskMap tương tự như Hashtable, các phương thức của HashMap không đồng bộ (unsynchornized) và cho phép khóa và giá trị có thể nhận giá trị null. HashMap được sử dụng để lưu trữ ánh xạ giá trị vào khóa tương ứng.
HashMap không phải là một Collection có thứ tự điều đó có nghĩa là các giá trị được lấy từ HashMap ra không theo thứ tự mà chúng đã được chèn vào trong HashMap.
Ví dụ về HashMap:
Chương trình sau cài đặt hầu hết các method quan trọng của HashMap. Để biết thêm chi tiết về các phương thức bạn có thể xem thêm tại đây
package simplecodecjava;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class SimpleCodeCJava {
    public static void main(String[] args) {
     HashMap<Integer, String> hmap = new HashMap<Integer, String>();
      /*Thêm giá trị tương ứng vào các key.*/
      hmap.put(12, "Hà Nội");
      hmap.put(2, "Đà Nẵng");
      hmap.put(7, "Nha Trang");
      hmap.put(49, "Thành Phố Hồ Chí Minh");
      hmap.put(3, "Cà Mau");
      /* Hiện thị giá trị bên trong HashMap sử dụng Iterator*/
      Set set = hmap.entrySet();
      Iterator iterator = set.iterator();
      while(iterator.hasNext()) {
         Map.Entry mentry = (Map.Entry)iterator.next();
         System.out.print("key is: "+ mentry.getKey() + " & Value is: ");
         System.out.println(mentry.getValue());
      }

      /* Lấy ra giá trị dựa vào key*/
      String var= hmap.get(2);
      System.out.println("Value at index 2 is: "+var);

      /* Xóa dữ liệu dựa vào key*/
      hmap.remove(3);
      System.out.println("Map key and values after removal:");
      Set set2 = hmap.entrySet();
      Iterator iterator2 = set2.iterator();
      while(iterator2.hasNext()) {
          Map.Entry mentry2 = (Map.Entry)iterator2.next();
          System.out.print("Key is: "+mentry2.getKey() + " & Value is: ");
          System.out.println(mentry2.getValue());
       }
   }
}
Kết quả chạy chương trình:
key is: 49 & Value is: Thành Phố Hồ Chí Minh
key is: 2 & Value is: Đà Nẵng
key is: 3 & Value is: Cà Mau
key is: 7 & Value is: Nha Trang
key is: 12 & Value is: Hà Nội
Value at index 2 is: Đà Nẵng
Map key and values after removal:
Key is: 49 & Value is: Thành Phố Hồ Chí Minh
Key is: 2 & Value is: Đà Nẵng
Key is: 7 & Value is: Nha Trang
Key is: 12 & Value is: Hà Nội
Danh sách phương thức của HashMap.
  1. void clear(): Loại bỏ tất cả các cặp khóa và giá trị ra khỏi HashMap.
  2. Object clone(): Trả về một bản copy tất cả các cặp khóa và giá trị, thường được sử dụng để sao chép sang một HashMap khác.
  3. boolean containsKey(Object key): trả về TRUE nếu trong HashMap có chứa key, trả về FALSE nếu trong HashMap không chứa key.
  4. boolean containsValue(Object value): trả về TRUE nếu trong HashMap có chứa value, trả về FALSE nếu trong HashMap không chứa value.
  5. Value get(Object key): Trả về giá trị được ánh xạ bởi key tương ứng.
  6. boolean isEmpty(): Thực hiện kiểm tra HashMap có rỗng hay không.
  7. Set keySet(): Trả về Set - danh sách tất cả các key được lấy từ HashMap.
  8. Value put(Key k, Value v): Chèn thêm value vào trong HashMap với key tương ứng.
  9. int size(): Trả về số lượng phần tử có trong HashMap.
  10. Collection values(): Trả về danh sách tất cả các giá trị có trong HashMap.
  11. Value remove(Object key): Trả về cặp khóa giá trị tương ứng với key truyền vào.
  12. void putAll(Map m): Copy tất cả các giá trị của HashMap vào Map truyền vào.