Java:检索 ArrayList 的随机不连续子列表(最有效的方法)
Java: Retrieve a random discontinuous Sublist of an ArrayList (most efficient way)
简而言之,我的问题是:
检索具有给定大小的 ArrayList 的随机不连续子列表的最有效方法是什么。
以下是我自己的设计,它可以工作,但对我来说似乎有点笨拙。顺便说一句,这是我的第一个 JAVA 程序,所以如果我的代码或问题不符合最佳实践,请原谅 ;)
备注:
- 我的列表不包含重复项
- 我 猜测 如果 AimSize 超过原始列表大小的一半,则删除项目而不是添加项目可能会更快
public ArrayList<Vokabel> subList(int AimSize) {
ArrayList<Vokabel> tempL = new ArrayList<Vokabel>();
Random r = new Random();
LinkedHashSet<Vokabel> tempS = new LinkedHashSet<Vokabel>();
tempL = originalList;
// If the size is to big just leave the list and change size
// (in the real code there is no pass-by-value problem ;)
if (!(tempL.size() > AimSize)) {
AimSize = tempL.size();
// set to avoid duplicates and get a random order
} else if (2* AimSize < tempL.size()) {
while (tempS.size() < AimSize) {
tempS.add(tempL.get(r.nextInt(tempL.size())));
}
tempL = new ArrayList<Vokabel>(tempS);
// little optimization if it involves less loops
// to delete entries to get to the right size, than to add them
// the List->Set->List conversion at the end is there to reorder the items
} else {
while (tempL.size() > AimSize) {
tempL.remove(r.nextInt(tempL.size()));
}
tempL = new ArrayList<Vokabel>(new LinkedHashSet<Vokabel>(tempL));
}
return tempL;
}
警告:这是在我的浏览器中编码的。它甚至可能无法编译!
使用 Collections.shuffle and List.subList 即可。
public static <T> List<T> randomSubList(List<T> list, int newSize) {
list = new ArrayList<>(list);
Collections.shuffle(list);
return list.subList(0, newSize);
}
另一个使用 Java 8 流的解决方案是这个
public static <T> List<T> selectRandomElements(List<T> list, int amount) {
if( amount > list.size())
throw new IllegalArgumentException("amount can't be bigger than list size");
return Stream.generate( () -> list.get( (int) ( Math.random() * list.size() ) ) )
.distinct()
.limit( amount )
.collect( Collectors.toList() );
}
简而言之,我的问题是: 检索具有给定大小的 ArrayList 的随机不连续子列表的最有效方法是什么。
以下是我自己的设计,它可以工作,但对我来说似乎有点笨拙。顺便说一句,这是我的第一个 JAVA 程序,所以如果我的代码或问题不符合最佳实践,请原谅 ;)
备注:
- 我的列表不包含重复项
- 我 猜测 如果 AimSize 超过原始列表大小的一半,则删除项目而不是添加项目可能会更快
public ArrayList<Vokabel> subList(int AimSize) {
ArrayList<Vokabel> tempL = new ArrayList<Vokabel>();
Random r = new Random();
LinkedHashSet<Vokabel> tempS = new LinkedHashSet<Vokabel>();
tempL = originalList;
// If the size is to big just leave the list and change size
// (in the real code there is no pass-by-value problem ;)
if (!(tempL.size() > AimSize)) {
AimSize = tempL.size();
// set to avoid duplicates and get a random order
} else if (2* AimSize < tempL.size()) {
while (tempS.size() < AimSize) {
tempS.add(tempL.get(r.nextInt(tempL.size())));
}
tempL = new ArrayList<Vokabel>(tempS);
// little optimization if it involves less loops
// to delete entries to get to the right size, than to add them
// the List->Set->List conversion at the end is there to reorder the items
} else {
while (tempL.size() > AimSize) {
tempL.remove(r.nextInt(tempL.size()));
}
tempL = new ArrayList<Vokabel>(new LinkedHashSet<Vokabel>(tempL));
}
return tempL;
}
警告:这是在我的浏览器中编码的。它甚至可能无法编译!
使用 Collections.shuffle and List.subList 即可。
public static <T> List<T> randomSubList(List<T> list, int newSize) {
list = new ArrayList<>(list);
Collections.shuffle(list);
return list.subList(0, newSize);
}
另一个使用 Java 8 流的解决方案是这个
public static <T> List<T> selectRandomElements(List<T> list, int amount) {
if( amount > list.size())
throw new IllegalArgumentException("amount can't be bigger than list size");
return Stream.generate( () -> list.get( (int) ( Math.random() * list.size() ) ) )
.distinct()
.limit( amount )
.collect( Collectors.toList() );
}