[java优先队列PriorityQueue的使用]
PriorityQueue弹出优先级最高的元素,优先级的比较是通过元素实现Comparable接口或者传入一个Comparator参数构造队列实现元素的比较而计算出优先级的。像Integer、String和Character这样的内置类型,默认使用12345 abcd一样的自然排序。对于其他对象,默认会抛出异常。
常用方法:offer() 插入一个对象,这个对象会被排序,失败返回falseadd() 插入一个对象,这个对象会被排序,失败抛出异常poll() 返回优先级最高的元素,并删除该元素 没有元素返回nullremove()返回优先级最高的元素,并删除该元素,没有元素抛出异常peek() 返回优先级最高的元素,不删除该元素,没有元素返回nullelement() 返回优先级最高的元素,不删除该元素,没有元素抛出异常
文档中推荐使用 offer()和poll()。要注意的是PriorityQueue维护的并不是一个有序表,并不保证所有元素有序,只确保弹出的是优先级最高的元素。
import
java.util.LinkedList;
import
java.util.PriorityQueue;
import
java.util.Queue;
import
java.util.Random;
class
Student
implements
Comparable {
String name;
int
age;
public
Student(String name,
int
age) {
super
();
this
.name = name;
this
.age = age;
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
int
getAge() {
return
age;
}
public
void
setAge(
int
age) {
this
.age = age;
}
@Override
public
String toString() {
return
"Student [name="
- name +
", age=" - age +
"]"
;
}
@Override
public
int
compareTo(Object arg0) {
Student s = (Student) arg0;
return
this
.age < s.getAge() ? -
1
:
this
.age == s.getAge() ?
0
:
1
;
}
}
public
class
PriorityQueueDemo {
public
static
void
main(String[] args) {
Queue<Integer> pq0 =
new
LinkedList<Integer>();
Random random =
new
Random();
for
(
int
i =
0
; i <
10
; i++) {
pq0.add(
new
Integer(random.nextInt(
100
)));
}
pq0.offer(
123
);
System.out.println(
"queue:"
);
System.out.println(pq0);
System.out.println(pq0.poll());
System.out.println(pq0);
Queue<Integer> pq1 =
new
PriorityQueue<Integer>();
for
(
int
i =
0
; i <
10
; i++) {
pq1.add(
new
Integer(random.nextInt(
100
)));
}
System.out.println(
"PriorityQueue:"
);
System.out.println(pq1);
System.out.println(pq1.poll());
System.out.println(pq1);
Queue<Student> pq =
new
PriorityQueue<Student>();
Student s1 =
new
Student(
"zhang1"
,
24
);
Student s2 =
new
Student(
"zhang2"
,
23
);
Student s3 =
new
Student(
"zhang3"
,
25
);
Student s4 =
new
Student(
"zhang4"
,
22
);
pq.add(s1);
pq.add(s2);
pq.add(s3);
pq.add(s4);
System.out.println(pq);
System.out.println(pq.poll());
}
}
执行结果:queue:[57, 47, 65, 46, 55, 13, 6, 61, 36, 60, 123]57[47, 65, 46, 55, 13, 6, 61, 36, 60, 123]PriorityQueue:[9, 11, 18, 18, 41, 38, 22, 64, 34, 86]9[11, 18, 18, 34, 41, 38, 22, 64, 86][Student [name=zhang4, age=22], Student [name=zhang2, age=23], Student [name=zhang3, age=25], Student [name=zhang1, age=24]]Student [name=zhang4, age=22]
设计模式
作者 codercjg 在 18 一月 2015, 4:26 下午
行为模式:1.观察者模式应用场景:当一个对象发生改变时,通知一个或多个依赖它的对象,java提供了类Observable和接口Observer分别代表被观察者和观察者。
import
java.util.Observable;
import
java.util.Observer;
//观察者
class
Watched
extends
Observable {
private
String data =
""
;
public
void
setData(String data) {
if
(!
this
.data.equals(data)) {
this
.data = data;
this
.setChanged();
this
.notifyObservers();
}
}
public
String getData() {
return
data;
}
}
//被观察者
class
Watcher
implements
Observer {
@Override
public
void
update(Observable arg0, Object arg1) {
System.out.println(
"changed "
- ((Watched) arg0).getData());
}
}
public
class
ObserverDemo {
public
static
void
main(String[] args) {
Observer watcher =
new
Watcher();
Watched watched =
new
Watched();
System.out.println(
"add observer"
);
watched.addObserver(watcher);
watched.setData(
"1"
);
watched.setData(
"2"
);
watched.setData(
"2"
);
watched.deleteObserver(watcher);
System.out.println(
"delete observer"
);
watched.setData(
"4"
);
}
}
2.模板方法模式使用场景:在模板中实现不会改变的算法框架,通过一个抽象方法把会变化的算法步骤延迟到子类中实现
abstract
class
Mp3Download {
// 延迟到子类中实现
protected
abstract
String search(String songTitle);
private
void
download(String url) {
System.out.println(
"download "
- url);
}
// 模板方法
public
void
getMp3(String songTitle) {
String title = search(songTitle);
download(title);
}
}
class
BaiduMp3
extends
Mp3Download {
@Override
protected
String search(String songTitle) {
System.out.println(
"baidu searching "
- songTitle);
String url =
"http://www.baidu.com/"
- songTitle;
return
url;
}
}
class
GoogleMp3
extends
Mp3Download {
@Override
protected
String search(String songTitle) {
System.out.println(
"Google searching "
- songTitle);
String url =
"http://www.Google.com/"
- songTitle;
return
url;
}
}
public
class
TemplateDemo {
public
static
void
main(String[] args) {
Mp3Download googleDownload =
new
GoogleMp3();
Mp3Download baiduDownload =
new
BaiduMp3();
googleDownload.getMp3(
"my heart will go on"
);
baiduDownload.getMp3(
"my heart will go on"
);
}
}
3.策略模式使用场景:算法实现与算法调用分离,使软件有很多可替换的算法实现,比如java集合类中的Comparator
interface
Strategy{
int
compare(
int
a,
int
b);
}
class
Strategy1
implements
Strategy{
@Override
public
int
compare(
int
a,
int
b) {
return
a<b?
1
:
0
;
}
}
class
Strategy2
implements
Strategy{
@Override
public
int
compare(
int
a,
int
b) {
return
a>b?
1
:
0
;
}
}
class
Context{
private
Strategy strategy;
public
Context(Strategy strategy){
this
.strategy = strategy;
}
public
Strategy getStrategy() {
return
strategy;
}
public
void
setStrategy(Strategy strategy) {
this
.strategy = strategy;
}
public
int
compare(
int
a,
int
b) {
return
strategy.compare(a, b);
}
}
public
class
StrategyDemo {
public
static
void
main(String[] args) {
Strategy s1 =
new
Strategy1();
Strategy s2 =
new
Strategy2();
Context context =
new
Context(s1);
context.compare(
1
,
2
);
context.setStrategy(s2);
context.compare(
1
,
2
);
}
}
4.状态模式使用场景:对象有很多种状态,每一种状态都需要表现不同的行为
interface
State {
void
handle();
void
next(StateManager stateMachine);
}
class
State1
implements
State {
@Override
public
void
handle() {
System.out.println(
"state1"
);
}
@Override
public
void
next(StateManager stateMachine) {
stateMachine.setState(
new
State2());
}
}
class
State2
implements
State {
@Override
public
void
handle() {
System.out.println(
"state2"
);
}
@Override
public
void
next(StateManager stateMachine) {
stateMachine.setState(
new
State3());
}
}
class
State3
implements
State {
@Override
public
void
handle() {
System.out.println(
"state3"
);
}
@Override
public
void
next(StateManager stateMachine) {
stateMachine.setState(
null
);
}
}
class
StateManager {
private
State state;
public
StateManager(State state) {
this
.state = state;
}
public
State getState() {
return
state;
}
public
void
setState(State state) {
this
.state = state;
}
public
void
manageState() {
if
(state !=
null
){
state.handle();
state.next(
this
);
}
}
}
public
class
StateDemo {
public
static
void
main(String[] args) {
State state1 =
new
State1();
StateManager stateManager =
new
StateManager(state1);
while
(stateManager.getState() !=
null
){
stateManager.manageState();
}
}
}
创建模式:1.单例模式使用场景:确保该类只存在一个对象
class
SingleObj {
private
static
volatile
SingleObj instance;
// 私有构造函数保证其他类中不能通过new创建对象
private
SingleObj() {
}
// 保证多线程环境中只创建一个对象
public
static
SingleObj getInstance() {
if
(instance ==
null
) {
synchronized
(SingleObj.
class
) {
if
(instance ==
null
) {
instance =
new
SingleObj();
}
}
}
return
instance;
}
}
ListView+ViewHolder模式+线程池
作者 codercjg 在 16 一月 2015, 10:11 下午
ListView重绘时会调用getView(int position, View convertView, ViewGroup parent)方法,其中的convertView有可能会被重用。ViewHold模式是用的很普遍的了。多个线程异步下载刷新ListView中进度条时因为convertView的重用需要注意避免显示错位。当listView的layout_height设置为wrap_content时,会多次重复调用getView(), 如果设置为match_parent就没问题了。
<?
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
"horizontal"
<
TextView
android:id
"@+id/taskid"
android:layout_width
"wrap_content"
android:layout_height
"wrap_content"
android:text
"111"
/>
<
ProgressBar
android:id
"@+id/progressbar"
android:layout_width
"match_parent"
android:layout_height
"15dip"
style
"@android:style/Widget.ProgressBar.Horizontal"
android:max
"100"
/>
</
LinearLayout
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
xmlns:tools
"http://schemas.android.com/tools"
android:id
"@+id/container"
android:layout_width
"match_parent"
android:layout_height
"match_parent"
tools:context
"com.codercjg.threadtest.MainActivity"
tools:ignore
"MergeRootFrame"
android:orientation
"vertical"
<
ListView
android:id
"@+id/listview"
android:layout_width
"match_parent"
android:layout_height
"match_parent"
</
ListView
</
LinearLayout
package
com.codercjg.threadtest;
import
java.util.ArrayList;
import
java.util.HashMap;
import
java.util.List;
import
java.util.Map;
import
java.util.concurrent.ExecutorService;
import
java.util.concurrent.Executors;
import
android.content.Context;
import
android.os.AsyncTask;
import
android.os.Bundle;
import
android.os.SystemClock;
import
android.support.v7.app.ActionBarActivity;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
import
android.widget.BaseAdapter;
import
android.widget.ListView;
import
android.widget.ProgressBar;
import
android.widget.TextView;
public
class
MainActivity
extends
ActionBarActivity {
private
static
ExecutorService singleTaskExcutor = Executors.newSingleThreadExecutor();
// 列表项一个一个的刷新进度
private
static
ExecutorService limitedTaskExcutor = Executors.newFixedThreadPool(
10
);
// 10个列表项一起刷新进度
private
static
ExecutorService fullTaskExcutor = Executors.newCachedThreadPool();
// 所有列表项一起刷新进度
private
MyListAdapter listAdapter;
private
List<String> resPaths =
new
ArrayList<String>();
private
Map<String, ResInfo> map =
new
HashMap<String, ResInfo>();
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listview);
listAdapter =
new
MyListAdapter(
this
,
40
);
listView.setAdapter(listAdapter);
}
private
class
MyAsyncTask
extends
AsyncTask<Void, Integer, Void> {
private
String resPath;
public
MyAsyncTask(String resPath) {
this
.resPath = resPath;
}
@Override
protected
void
onProgressUpdate(Integer... values) {
super
.onProgressUpdate(values);
ResInfo resInfo = map.get(resPath);
resInfo.progress = values[
0
];
if
(resInfo.holder !=
null
){
// 如果列表项已被用于显示其他资源进度
resInfo.holder.progBar.setProgress(values[
0
]);
}
}
@Override
protected
Void doInBackground(Void... arg0) {
int
prog =
0
;
while
(prog <
100
) {
SystemClock.sleep(
100
);
prog++;
publishProgress(prog);
}
return
null
;
}
}
private
class
MyListAdapter
extends
BaseAdapter {
private
Context context;
private
LayoutInflater inflater;
private
int
count;
public
MyListAdapter(Context context,
int
count) {
this
.context = context;
this
.count = count;
inflater = LayoutInflater.from(context);
String path;
ResInfo resInfo;
for
(
int
i =
0
; i < count; i++) {
path = String.valueOf(i);
resPaths.add(path);
resInfo =
new
ResInfo();
map.put(path, resInfo);
}
}
@Override
public
int
getCount() {
return
resPaths.size();
}
@Override
public
Object getItem(
int
arg0) {
return
resPaths.get(arg0);
}
@Override
public
long
getItemId(
int
position) {
return
position;
}
@Override
public
View getView(
int
position, View convertView, ViewGroup parent) {
ViewHolder holder;
if
(convertView ==
null
) {
convertView = inflater.inflate(R.layout.my_list_item, parent,
false
);
holder =
new
ViewHolder();
holder.progBar = (ProgressBar) convertView.findViewById(R.id.progressbar);
holder.textView = (TextView) convertView.findViewById(R.id.taskid);
holder.resPath = resPaths.get(position);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
System.out.println(
"recycle item id:"
- holder.resPath);
}
String resPath = resPaths.get(position);
ResInfo resInfo = map.get(resPath);
if
(resInfo.task ==
null
) {
// 如果当前列表项关联的资源没有线程下载
MyAsyncTask task =
new
MyAsyncTask(resPath);
//创建一个线程
resInfo.task = task;
// task.execute(); // 一次执行一个线程
// task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);//一列表项刷新
// task.executeOnExecutor(singleTaskExcutor); // 一列表项刷新
// task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);//多个线程一起执行和具体系统
//task.executeOnExecutor(limitedTaskExcutor); // 10个列表项一起刷新,
task.executeOnExecutor(fullTaskExcutor);
// 所有列表项一起刷新
}
if
(holder.resPath != resPath) {
// 如果当前列表项已经显示了资源,但不是当前资源
map.get(holder.resPath).holder =
null
;
holder.resPath = resPath;
}
map.get(resPaths.get(position)).holder = holder;
holder.textView.setText(resPath);
holder.progBar.setProgress(resInfo.progress);
return
convertView;
}
}
private
static
class
ViewHolder {
public
ProgressBar progBar;
public
TextView textView;
public
String resPath;
}
private
class
ResInfo {
int
progress;
ViewHolder holder;
MyAsyncTask task;
}
}
网友评论