功能说明:从一个List对象中均匀抽选出固定数量的样本。
import lombok.Getter;
import java.util.LinkedList;
import java.util.List;
public abstract class Sample {
//样本数据
protected List sampleData;
//抽取的样本数
protected int sampleTotal;
@Getter
//采样的元素索引
protected List sampleIndex;
public abstract void execute();
public void sample(){
if(sampleTotal <= 0){
throw new IllegalArgumentException("采样参数不正确");
}
if(sampleData.size() <= sampleTotal){
for (int i = 0; i < sampleData.size(); i++) {
sampleIndex.add(i);
}
}else{
this.execute();
}
}
public List getResult() {
List result = new LinkedList<>();
for (Integer i : sampleIndex) {
result.add(sampleData.get(i));
}
return result;
}
}
package com.zhou.chart.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 实现均匀采样(保留首尾)
* @author lang.zhou
* @date 2022/6/23 14:34
*/
public class HeadTailSample extends Sample{
public HeadTailSample(List sampleData, int sampleTotal) {
this.sampleData = sampleData;
this.sampleTotal = sampleTotal;
this.sampleIndex = new ArrayList<>(sampleTotal);
}
public void execute(){
int size = sampleData.size();
float sec = (size+0.0f)/(sampleTotal - 1);
if(size <= sampleTotal){
return;
}
sampleIndex.add(0);
float mark = sec;
for (int i = 1; i < size; i++) {
float cu = i + 0.0f;
float rate = Math.abs(mark - cu);
//补偿因子
if(rate < 1){
sampleIndex.add(i);
//保证采样数量不多于sampleTotal
if(sampleIndex.size()>= sampleTotal){
break;
}
mark+= sec;
}
}
if(!sampleIndex.contains(size - 1)){
if(sampleIndex.size()>= sampleTotal){
sampleIndex.remove(sampleIndex.size() - 1);
}
sampleIndex.add(size - 1);
}
}
public static void main(String[] args) {
//5
test(3,1,2,3,4,5,6,7,8);
test(5,1,2,3,4,5);
test(5,1,2,3,4,5,6);
test(5,1,2,3,4,5,6,7);
test(5,1,2,3,4,5,6,7,8);
test(5,1,2,3,4,5,6,7,8,9);
test(5,1,2,3,4,5,6,7,8,9,10);
test(5,1,2,3,4,5,6,7,8,9,10,11);
test(5,1,2,3,4,5,6,7,8,9,10,11,12);
test(5,1,2,3,4,5,6,7,8,9,10,11,12,13);
test(5,1,2,3,4,5,6,7,8,9,10,11,12,13,14);
test(5,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
}
private static void test(int cnt,Integer ... a){
List l = Arrays.asList(a);
Sample sample = new HeadTailSample<>(l, cnt);
sample.sample();
List list = sample.getResult();
System.out.println(Arrays.toString(list.toArray()));
}
}
public abstract class Sample {
//样本数据
protected List sampleData;
//抽取的样本数
protected int sampleTotal;
@Getter
//采样的元素索引
protected List sampleIndex;
public abstract void execute();
public void sample(){
if(sampleTotal <= 0){
throw new IllegalArgumentException("采样参数不正确");
}
if(sampleData.size() <= sampleTotal){
for (int i = 0; i < sampleData.size(); i++) {
sampleIndex.add(i);
}
}else{
this.execute();
}
}
public List getResult() {
List result = new LinkedList<>();
for (Integer i : sampleIndex) {
result.add(sampleData.get(i));
}
return result;
}
}
运行结果: