Reputation: 1891
I wish I could be more concise in my title, but I'm not quite sure how to describe what I want to do. I have a list containing a number of objects of a class I've made. Each object has a number of attributes, accessible by some getters and setters. I would like to create a list for each attribute, get the attributes of each object and put them into their respective lists.
I'm currently doing this with the code below:
ArrayList<Integer> counts = new ArrayList<Integer>();
ArrayList<String> colors = new ArrayList<String>();
ArrayList<String> shapes = new ArrayList<String>();
ArrayList<String> fills = new ArrayList<String>();
for (Card card: cards) {
counts.add(card.getCount());
colors.add(card.getColor());
shapes.add(card.getShape());
fills.add(card.getFill());
}
But I'm wondering if there's a shorter, maybe better, way to do this? Or am I doing it the "proper" already? Thanks!
Upvotes: 1
Views: 63
Reputation: 3058
If you are developing a set game, here is a solution for checking and completing card sets:
Card.java:
import java.util.Locale;
public final class Card {
public static void main(String[] args) {
Card a = new Card(Count.ONE, Color.RED, Fill.STRIPED, Shape.DIAMOND);
Card b = new Card(Count.TWO, Color.RED, Fill.SOLID, Shape.DIAMOND);
Card c = completeSet(a, b);
System.out.println(c);
}
public int count;
public int color;
public int fill;
public int shape;
public Card() {
}
public Card(Count count, Color color, Fill fill, Shape shape) {
setCount(count);
setColor(color);
setFill(fill);
setShape(shape);
}
// getters and setters to operate with the attribute enumerations
public Count getCount() {
return Count.values()[count];
}
public Color getColor() {
return Color.values()[color];
}
public Shape getShape() {
return Shape.values()[shape];
}
public Fill getFill() {
return Fill.values()[fill];
}
public void setCount(Count count) {
this.count = count.ordinal();
}
public void setColor(Color color) {
this.color = color.ordinal();
}
public void setShape(Shape shape) {
this.shape = shape.ordinal();
}
public void setFill(Fill fill) {
this.fill = fill.ordinal();
}
public static int completeAttribute(int a, int b) {
if (a == b) {
// attribute for each same
return a;
} else {
// attribute for each different
int c;
for (c = 0; c < 3; c++) {
if (c != a && c != b) {
break;
}
}
return c;
}
}
public static Card completeSet(Card a, Card b) {
// determine missing card to make a set
Card result = new Card();
result.count = completeAttribute(a.count, b.count);
result.color = completeAttribute(a.color, b.color);
result.shape = completeAttribute(a.shape, b.shape);
result.fill = completeAttribute(a.fill, b.fill);
return result;
}
public static boolean isSet(Card a, Card b, Card c) {
// check if it is a set by completing it
return completeSet(a, b).equals(c);
}
@Override
public boolean equals(Object that) {
// currently unused
if (this == that) {
return true;
}
return that != null && that instanceof Card && this.equals((Card) that);
}
public boolean equals(Card that) {
if (this == that) {
return true;
}
return that != null
&& this.color == that.color
&& this.count == that.count
&& this.fill == that.fill
&& this.shape == that.shape;
}
@Override
public int hashCode() {
// currently unused
int result = count;
result = 31 * result + color;
result = 31 * result + shape;
result = 31 * result + fill;
return result;
}
@Override
public String toString() {
// pretty print attributes
String result = getCount() + " " + getColor() + " " + getFill() + " " + getShape();
result = result.toLowerCase(Locale.ROOT);
if(getCount() != Count.ONE) {
result += "s";
}
return result;
}
// enumerations for pretty names
public enum Count {
ONE,
TWO,
THREE
}
public enum Color {
RED,
GREEN,
VIOLET
}
public enum Shape {
ELLIPSE,
DIAMOND,
TWIRL
}
public enum Fill {
OPEN,
STRIPED,
SOLID
}
}
Output: three red open diamonds
Upvotes: 1
Reputation: 394146
Your way looks fine. You can write it with less lines of code if you use Java 8 Streams, but that would require 4 iterations over the cards
list instead of the single iteration you currently have.
For example, to create the list of counts, you can write :
List<Integer> counts = cards.stream().map(Card::getCount).collect(Collectors.toList());
Upvotes: 1