1

I have an arraylist of objects ArrayList<Tile> list Tile has attributes of new Tile("colour", value) I want to make a search function where I iterate though each Colour attribute of the Tile and each Value attribute within each colour in the arraylist (like a nested for each loop), is there an easy way of doing this?

Prady
  • 165
  • 1
  • 15

1 Answers1

3

Assuming Tile class has two attributes a String colour and an int value. It has a toString (java.lang.Object class's override method) like this:

@Override public String toString() {
    return colour + ":" + value;
}

Make some tiles:

Tile t1 = new Tile("red", 7); // constructor takes a colour and a value
Tile t2 = new Tile("red", 2);
Tile t3 = new Tile("blue", 9);
Tile t4 = new Tile("white", 17);
Tile t5 = new Tile("blue", 3);
Tile t6 = new Tile("red", 15);
Tile t7 = new Tile("white", 10);


Scenario 1:

The function takes a list of Tile objects and a String colour as input and returns all tiles with the input colour (and their values). There are two ways to do that and these are shown in two methods:

private static List<Tile> getTilesWithColor1(List<Tile> tilesList, String searchColor) {
    return tilesList.stream()
                     .filter(tile -> tile.getColour().equals(searchColor))
                     .collect(Collectors.toList());
}

private static List<Tile> getTilesWithColor2(List<Tile> tilesList, String searchColor) {
    List<Tile> result = new ArrayList<>();
    for (Tile t : tilesList) {
        if (t.getColour().equals(searchColor)) {
            result.add(t);
        }
    }
    return result;
}
  • The input: tilesList, colour="red"
  • The output (from both methods is same): [red:7, red:2, red:15]

I want to make a search function where I iterate though each Colour attribute of the Tile and each Value attribute within each colour in the arraylist (like a nested for each loop), is there an easy way of doing this?

One can alter this function to add additional conditions or filters to get required result.


Scenario 2:

Get all colors and their values:

private static Map<String, List<Integer>> getTileColorsAndValues(List<Tile> tilesList) {
    return tilesList.stream()
                     .collect(Collectors.groupingBy(Tile::getColour,
                         Collectors.mapping(Tile::getValue, Collectors.toList())));
}
  • The input: tilesList
  • The output: {red=[7, 2, 15], white=[17, 10], blue=[9, 3]}

Note one can get the values within the "red" tiles like this from the resulting map:

List<Integer> valuesList = map.get("red");


Scenario 3:

Get all tiles by color:

private static Map<String, List<Tile>> getTilesByColorsAndValues(List<Tile> tilesList) {
    return tilesList.stream()
                    .collect(Collectors.groupingBy(Tile::getColour));
}
  • The input: tilesList
  • The output: {red=[red:7, red:2, red:15], white=[white:17, white:10], blue=[blue:9, blue:3]}

Note one can get the tiles within the "red" tiles like this from the resulting map:

List<Tile> tilesList = map.get("red");



The Example's Code:

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class TilesExample {

    public static void main(String [] args) {

        Tile t1 = new Tile("red", 7);
        Tile t2 = new Tile("red", 2);
        Tile t3 = new Tile("blue", 9);
        Tile t4 = new Tile("white", 17);
        Tile t5 = new Tile("blue", 3);
        Tile t6 = new Tile("red", 15);
        Tile t7 = new Tile("white", 10);
        List<Tile> tilesList = Arrays.asList(t1, t2, t3, t4, t5, t6, t7);

        System.out.println(getTilesWithColor1(tilesList, "red"));
        System.out.println(getTilesWithColor2(tilesList, "red"));

        System.out.println(getTileColorsAndValues(tilesList));

        System.out.println(getTilesByColorsAndValues(tilesList));
    }

    private static Map<String, List<Tile>> getTilesByColorsAndValues(List<Tile> tilesList) {
        return tilesList.stream()
                        .collect(Collectors.groupingBy(Tile::getColour));
    }

    private static Map<String, List<Integer>> getTileColorsAndValues(List<Tile> tilesList) {
        return tilesList.stream()
                        .collect(Collectors.groupingBy(Tile::getColour,
                            Collectors.mapping(Tile::getValue, Collectors.toList())));
    }

    private static List<Tile> getTilesWithColor1(List<Tile> tilesList, String searchColor) {
        return tilesList.stream()
                         .filter(tile -> tile.getColour().equals(searchColor))
                         .collect(Collectors.toList());
    }

    private static List<Tile> getTilesWithColor2(List<Tile> tilesList, String searchColor) {
        List<Tile> result = new ArrayList<>();
        for (Tile t : tilesList) {
            if (t.getColour().equals(searchColor)) {
                result.add(t);
            }
        }
        return result;
    }
}
prasad_
  • 12,755
  • 2
  • 24
  • 36
  • Thanks a bunch! this was very helpful. I really appreciate it – Prady Oct 05 '18 at 23:18
  • Did it answer your question? If so, which aspect of it? – prasad_ Oct 06 '18 at 01:32
  • 1
    all 3 solutions were helpful, solution 3 in particular helped me with the main search issue, and the other 2 solutions helped me with other problems I was having trouble with – Prady Oct 07 '18 at 23:20