假设我有一个包含两个字段field1
和field2
的对象列表,这两个字段都是字符串类型。
如果可能的话,如何获取所有field1
值的列表而不必迭代列表?
答案 0 :(得分:23)
幸运的是,您可以使用 Java 8 - Streams
执行此操作假设您有一个名为 YourEntity
的实体public class YourEntity {
private String field1;
private String field2;
public YourEntity(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
public void setField1(String field1) {
this.field1 = field1;
}
public void setField2(String field2) {
this.field2 = field2;
}
public String getField1() {
return field1;
}
public String getField2() {
return field2;
}
}
使用:
声明 YourEntity 的列表List<YourEntity> entities = Arrays.asList(new YourEntity("text1", "text2"), new YourEntity("text3", "text4"));
您可以通过以下方式一次性提取 field1 列表:
import java.util.stream.Collectors;
List<String> field1List = entities.stream().map(YourEntity::getField1).collect(Collectors.toList());
或以这种方式
import java.util.stream.Collectors;
List<String> field1List = entities.stream().map(urEntity -> urEntity.getField1()).collect(Collectors.toList());
您也可以使用java 8 :)打印所有项目。
field1List.forEach(System.out::println);
输出
text1
text3
答案 1 :(得分:8)
试试这个:
List<Entity> entities = getEntities();
List<Integer> listIntegerEntities = Lambda.extract(entities, Lambda.on(Entity.class).getFielf1());
LambdaJ允许访问没有显式循环的集合,因此不要让更多的代码行自己迭代列表,而是让LambdaJ去做。
答案 2 :(得分:4)
对象是对内存地址的引用。然后,此对象的字段是对其他内存地址的其他引用。 因此,对象列表是引用列表。因此,列表无法直接访问对象字段(引用给出的引用)。简短的回答是否定的。
注意:无论如何,您都会找到一个能够满足您需求的API,它仍会在内部循环。
答案 3 :(得分:4)
java作为语言和JDK库都没有做你想做的事。您可以使用LambdaJ或等待预计包含lambda表达式的Java 8。
答案 4 :(得分:3)
...您的问题是否也引用avoiding iterating over the collection
:
具体来说,你的意思是:
请参阅下面的解决方案和选项。
如果是第一个,那么请查看Google Guava,LambdaJ,FunctionalJava或其他实现基本功能构造的库,并允许您在一些富有表现力的调用中执行您想要的操作。但请记住,这些做了锡上的内容:它们将过滤,收集或转换集合,并将迭代其元素来执行此操作。
例如:
Set<String> strings = buildSetStrings();
Collection<String> filteredStrings =
Collections2.filter(strings, Predicates.containsPattern("^J"));
Array<Integer> a = array(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42);
Array<Integer> b = a.filter(even);
List<Integer> biggerThan3 = filter(greaterThan(3), asList(1, 2, 3, 4, 5));
如果是第二个,这是不可能的,除了,如果您从一开始就构建了所有内容,以便您的对象应该由自定义集合类,可根据插入时的字段值为对象编制索引。
它会将它们保存在由所述值索引的桶中,以便您可以将它们作为列表检索或按需设置。
正如下面的评论中所提到的,dounyy的答案是,设计这样的自定义集合可能会对它接受的元素的API产生影响(最有可能通过定义用于元素类型的超级接口),或者需要如果您希望此集合是通用的,那么动态解析成员的相当复杂的实现(很可能通过使用反射)。
答案 5 :(得分:1)
是!!这是可能的。 但你必须做一些弯曲的工作。
使用必需变量创建内部类。 例如:这里将使用2个变量。(TNAME和TABTYPE)。
public class storeTables {
private String tablename = "";
private String tabletype = "";
public storeTables(String a, String b)
{
this.setTablename(a);
this.setTabletype(b);
}
public void setTablename(String tablename) {
this.tablename = tablename;
}
public String getTablename() {
return tablename;
}
public void setTabletype(String tabletype) {
this.tabletype = tabletype;
}
public String getTabletype() {
return tabletype;
}}
创建上面创建的内部类的列表,不要忘记封装它。
private List<storeTables> objlist= new ArrayList<storeTables>();
将存储的值作为内部类对象获取。
String Query="SELECT * FROM TAB";
while(rs.next())
{
String tname=rs.getString("TNAME");
String tabtype=rs.getString("TABTYPE");
getObjlist().add(new storeTables(tname,tabtype));
}
创建DATAMODEL并将列表推送到datamodel
private DataModel selectableItems= new ListDataModel(objlist);
将变形数据输入另一个列表。
List<storeTables> items= (List<storeTables>)selectableItems.getWrappedData();
最后!!!打印数据。
for(storeTables item:items){
System.out.println(item.getTablename());
}
答案 6 :(得分:1)
古老的问题,但我想看看我是否可以改进类似的解决方案。
您可以实现List<String>
接口而无需创建充实的ArrayList<String>
,因此不会迭代父对象。
final List<Entity> entities = getEntities()
final List<String> field1 = new AbstractList() {
public String get(int index) {
return entities.get(index).getField1();
}
public int size() {
return entities.size();
}
}
它为您提供了一个List而不迭代父对象。
随机访问派生的List<String>
将与对基础List<Entity>
的随机访问一样昂贵;如果您正在使用不提供快速随机访问的List<Entity>
实现,您可能需要跳过几个环节(即实现List<String>
的更多方法。但这应该适用于99%的情况下你需要一个轻量级适配器。
答案 7 :(得分:0)
答案 8 :(得分:0)
也许你可以用这种方式创建一个hashmap:
HashMap<String, ArrayList<Object>> map;
关键是该领域。 这样做时,当你要求HashMap检索对应于你想要的字段的对象时,地图会返回一个ArrayList,其中包含具有该字段的所有元素。
答案 9 :(得分:0)
没有迭代,这是不可能的。你可以以某种方式减少迭代,但这是必须的。
答案 10 :(得分:0)
在不同的列表中添加记录的值,并使用一个或两个迭代器简单地打印 单独的值。如下:
rs=st.executeQuery("select * from stu");
List data=new ArrayList();
List data1=new ArrayList();
while(rs.next())
{
data.add(rs.getString(1));
data1.add(rs.getString(2));
}
Iterator it=data.iterator();
Iterator it1=data1.iterator();
while(it1.hasNext())
{
System.out.println(" "+it.next()+" "+it1.next());
}
答案 11 :(得分:0)
让该对象属于以下类。
public class Bike {
String bikeModel;
Int price;
}
现在有一个名为bikeList的自行车列表,类型为List
因此,现在我们需要以上列表中所有自行车的自行车型号列表。
bikeList.map{ Bike b -> b.bikeModel }.toCollection(arrayListOf())
返回bikeList中所有自行车对象的第一个字段的数组列表